<template>
  <div class="announcement-create">
    <a-card class="create-card">
      <template #title>
        <div style="display: flex; align-items: center; gap: 12px;">
          <img src="D:/下载/公告.png" alt="公告图标" style="width: 28px; height: 28px;" />
          <span style="font-size: 22px; font-weight: 600;">发布公告</span>
        </div>
      </template>
      <a-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        :label-col="{ span: 3 }"
        :wrapper-col="{ span: 20 }"
      >
        <!-- 基本信息 -->
        <div class="form-section">
          <div class="section-header">
            <span class="section-number">1</span>
            <span class="section-title">基本信息</span>
          </div>
        
        <a-form-item label="公告标题" name="title" required>
          <div class="title-input-wrapper">
            <a-input 
              v-model:value="formData.title" 
              placeholder="请输入公告标题（最多100字）"
              size="large"
              :maxlength="100"
              :bordered="false"
            />
          </div>
          <div class="title-char-count">{{ formData.title?.length || 0 }}/100</div>
        </a-form-item>
        </div>

        <!-- 模块2: 发布范围 -->
      <div class="form-section">
        <div class="section-header">
          <span class="section-number">2</span>
          <span class="section-title">发布范围</span>
        </div>
        
        <a-form-item label="发布范围" name="scope_type" required>
          <a-radio-group v-model:value="formData.scope_type" @change="handleScopeTypeChange">
            <a-radio value="全校">全校公告</a-radio>
            <a-radio value="院系" :disabled="userRole === '师生用户'">指定院系</a-radio>
            <a-radio value="年级" :disabled="userRole === '师生用户'">指定年级</a-radio>
            <a-radio value="班级" :disabled="userRole === '师生用户'">指定班级</a-radio>
          </a-radio-group>
        </a-form-item>

        <!-- 指定院系 -->
        <a-form-item 
          v-if="formData.scope_type === '院系'" 
          label="选择院系" 
          name="departments"
          required
        >
          <a-select
            v-model:value="formData.departments"
            mode="multiple"
            placeholder="请选择院系（可多选）"
            size="large"
            :options="departmentOptions"
            :field-names="{ label: 'name', value: 'id' }"
          />
        </a-form-item>

        <!-- 指定年级 -->
        <a-form-item 
          v-if="formData.scope_type === '年级'" 
          label="选择年级" 
          name="grades"
          required
        >
          <a-select
            v-model:value="formData.grades"
            mode="multiple"
            placeholder="请选择年级（可多选）"
            size="large"
            :options="gradeOptions"
          />
        </a-form-item>

        <!-- 指定班级 -->
        <a-form-item 
          v-if="formData.scope_type === '班级'" 
          label="选择班级" 
          name="classes"
          required
        >
          <a-select
            v-model:value="formData.classes"
            mode="multiple"
            placeholder="请选择班级（可多选）"
            size="large"
            :options="classOptions"
            :field-names="{ label: 'name', value: 'id' }"
          />
        </a-form-item>
        </div>

        <!-- 模块3: 公告设置 -->
        <div class="form-section">
          <div class="section-header">
            <span class="section-number">3</span>
            <span class="section-title">公告设置</span>
          </div>

        <a-form-item label="紧急程度" name="urgency_level" required>
          <div class="urgency-wrapper">
            <a-radio-group v-model:value="formData.urgency_level" class="urgency-radio-group">
              <a-radio value="普通">
                <span class="urgency-normal-text">普通</span>
              </a-radio>
              <a-radio value="重要">
                <span class="urgency-important-text">重要</span>
              </a-radio>
              <a-radio value="紧急">
                <span class="urgency-urgent-text">紧急</span>
              </a-radio>
            </a-radio-group>
            <span class="urgency-hint-right">（将弹窗强制提醒）</span>
          </div>
        </a-form-item>

        <a-form-item label="有效期" name="validity">
          <div class="validity-wrapper">
            <a-date-picker 
              v-model:value="validityStartTime"
              show-time
              format="YYYY-MM-DD HH:mm"
              placeholder="开始时间"
              size="large"
              class="validity-picker-start"
            />
            <span class="validity-arrow">→</span>
            <a-date-picker 
              v-model:value="validityEndTime"
              show-time
              format="YYYY-MM-DD HH:mm"
              placeholder="结束时间"
              size="large"
              class="validity-picker-end"
            />
            <span class="validity-tip">不设置则永久有效</span>
          </div>
        </a-form-item>

        <!-- 定时发布区域 - 自然选择区设计 -->
        <a-form-item label="" name="scheduled_time">
          <div class="scheduled-publish-container">
            <!-- 标题与开关整合 -->
            <div class="scheduled-header">
              <ClockCircleOutlined class="setting-icon" />
              <span class="scheduled-title">定时发布</span>
              <a-switch 
                v-model:checked="enableScheduledTime" 
                @change="handleScheduledTimeToggle"
                class="scheduled-switch"
              />
            </div>
            
            <div v-if="enableScheduledTime" class="time-selection-area">
              <!-- 快捷时间选择 - 标签式设计 -->
              <div class="quick-time-tags">
                <span 
                  v-for="option in quickTimeOptions" 
                  :key="option.label"
                  class="time-tag"
                  :class="{ 'time-tag-active': selectedQuickTime === option.label }"
                  @click="selectQuickTime(option)"
                >
                  {{ option.label }}
                </span>
                
                <!-- 自定义时间入口 - 文字+图标 -->
                <span 
                  class="custom-time-trigger"
                  :class="{ 'custom-time-active': isCustomTime }"
                  @click="showCustomTimePicker"
                >
                  <CalendarOutlined class="custom-time-icon" />
                  自定义时间
                </span>
              </div>
              
              <!-- 已选时间条 -->
              <div v-if="formData.scheduled_time" class="selected-time-bar">
                <ClockCircleOutlined class="time-bar-icon" />
                <span class="time-bar-text">{{ formatScheduledTime() }}</span>
                <span class="time-bar-clear" @click="clearScheduledTime">清除</span>
              </div>
              
              <div class="time-hint-note">
                不设置则立即发布
              </div>
            </div>
          </div>
        </a-form-item>

        <a-form-item label="" name="is_pinned">
          <div class="pinned-wrapper">
            <PushpinOutlined class="setting-icon" />
            <span class="pinned-title">是否置顶</span>
            <a-switch v-model:checked="formData.is_pinned" />
            <span class="pinned-hint">置顶公告将显示在列表顶部</span>
          </div>
        </a-form-item>
        </div>

        <!-- 模块4: 公告内容 -->
        <div class="form-section">
          <div class="section-header">
            <span class="section-number">4</span>
            <span class="section-title">公告内容</span>
          </div>
        
        <a-form-item label="公告内容" name="content" required>
          <div class="editor-container">
            <!-- 工具栏 -->
            <div class="editor-toolbar">
              <a-space>
                <!-- 标题按钮（新版三级系统） -->
                <a-button 
                  size="small" 
                  :type="currentHeadingLevel === 'large' ? 'primary' : 'default'"
                  @click="toggleHeading('large')"
                  class="toolbar-btn heading-btn"
                >
                  大标题
                </a-button>
                <a-button 
                  size="small" 
                  :type="currentHeadingLevel === 'medium' ? 'primary' : 'default'"
                  @click="toggleHeading('medium')"
                  class="toolbar-btn heading-btn"
                >
                  中标题
                </a-button>
                <a-button 
                  size="small" 
                  :type="currentHeadingLevel === 'small' ? 'primary' : 'default'"
                  @click="toggleHeading('small')"
                  class="toolbar-btn heading-btn"
                >
                  小标题
                </a-button>
                <a-divider type="vertical" />
                <a-button 
                  size="small" 
                  :type="isBold ? 'primary' : 'default'"
                  @click="insertBold" 
                  class="toolbar-btn"
                >
                  <strong>B</strong>
                </a-button>
                <a-button 
                  size="small" 
                  :type="isItalic ? 'primary' : 'default'"
                  @click="insertItalic" 
                  class="toolbar-btn"
                >
                  <em>I</em>
                </a-button>
                <a-button 
                  size="small" 
                  :type="isUnderline ? 'primary' : 'default'"
                  @click="insertUnderline" 
                  class="toolbar-btn"
                >
                  <u>U</u>
                </a-button>
                <a-divider type="vertical" />
                <a-button size="small" @click="insertList" class="toolbar-btn">
                  • 无序列表
                </a-button>
                <a-button size="small" @click="insertOrderedList" class="toolbar-btn">
                  1. 有序列表
                </a-button>
                <a-button size="small" @click="insertTable" class="toolbar-btn">
                   表格
                </a-button>
                <a-divider type="vertical" />
                <a-upload
                  :before-upload="handleImageUpload"
                  :show-upload-list="false"
                  accept="image/*"
                >
                  <a-button size="small" :loading="uploadingImage">插入图片</a-button>
                </a-upload>
              </a-space>
            </div>
            
            <!-- 富文本可视化编辑区（支持图片原图显示） -->
            <div class="rich-editor-wrapper">
              <!-- 可视化编辑模式 -->
              <div 
                v-show="previewTab === 'visual'"
                ref="visualEditor"
                class="visual-editor-area"
                contenteditable="true"
                @input="handleVisualEditorInput"
                @paste="handlePaste"
                @keydown="handleKeydown"
                @click="updateCurrentHeadingLevel"
                @keyup="updateCurrentHeadingLevel"
                @mouseup="updateFormatStates"
                @select="updateFormatStates"
              >
              </div>
              
              <!-- 预览区（基于统一数据源渲染）-->
              <div 
                v-show="previewTab === 'preview'"
                ref="previewArea"
                class="rich-preview-area"
              >
              </div>
            </div>
            
            <!-- 预览切换标签（移除源码编辑）-->
            <a-tabs v-model:activeKey="previewTab" class="preview-tabs" @change="handleTabChange">
              <a-tab-pane key="visual" tab="可视化编辑"></a-tab-pane>
              <a-tab-pane key="preview" tab="预览模式"></a-tab-pane>
            </a-tabs>
            
            <!-- 插入的图片列表管理（预览模式隐藏）-->
            <div v-if="insertedImages.length > 0 && previewTab !== 'preview'" class="inserted-images-manager">
              <a-divider orientation="left" style="font-size: 12px;">已插入图片 ({{ insertedImages.length }})</a-divider>
              <a-space wrap>
                <div 
                  v-for="(img, index) in insertedImages" 
                  :key="img.id"
                  class="image-item"
                  @click="focusOnImage(img.id)"
                >
                  <img :src="img.url" :alt="img.name" />
                  <div class="image-item-mask">
                    <a-space>
                      <a-button size="small" type="link" @click.stop="editImageStyle(img.id)">调整</a-button>
                      <a-button size="small" type="link" danger @click.stop="removeImage(img.id)">删除</a-button>
                    </a-space>
                  </div>
                </div>
              </a-space>
            </div>
          </div>
        </a-form-item>

        <!-- 附件上传 -->
        <a-form-item label="附件上传" name="attachments">
          <a-upload
            v-model:file-list="fileList"
            :before-upload="handleFileUpload"
            :remove="handleFileRemove"
            accept=".doc,.docx,.pdf,.xls,.xlsx,.ppt,.pptx"
            :max-count="5"
            list-type="text"
          >
            <a-button>
              <upload-outlined></upload-outlined>
              上传附件
            </a-button>
          </a-upload>
          <div class="tip">支持 docx、pdf、xls、ppt 格式，最多5个文件，单个文件不超过10MB</div>
        </a-form-item>
        </div>
        
        <!-- 操作按钮 -->
        <a-form-item :wrapper-col="{ offset: 3, span: 20 }">
          <a-space size="large" class="action-buttons-group">
            <a-button 
              size="large"
              class="preview-btn" 
              @click="handlePreview"
            >
              预览
            </a-button>
            <a-button 
              size="large"
              class="cancel-btn" 
              @click="handleSaveDraft"
              :loading="savingDraft"
            >
              保存草稿
            </a-button>
            <a-button 
              type="primary" 
              size="large" 
              @click="handleSubmit"
              :loading="submitting"
              class="submit-btn"
            >
              {{ formData.scheduled_time ? '定时发布' : '立即发布' }}
            </a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-card>

    <!-- 图片原图预览模态框 -->
    <a-modal
      v-model:open="imagePreviewVisible"
      :title="previewImageName || '图片预览'"
      width="90%"
      :footer="null"
      :centered="true"
      :bodyStyle="{ padding: '24px', textAlign: 'center', background: '#000' }"
      @cancel="imagePreviewVisible = false"
    >
      <div class="image-preview-container">
        <img 
          :src="previewImageUrl" 
          :alt="previewImageName"
          class="preview-image"
          @click="imagePreviewVisible = false"
        />
        <div class="preview-tips">
          <span>点击图片或空白处关闭预览</span>
        </div>
      </div>
    </a-modal>

    <!-- 自定义时间选择器模态框 -->
    <a-modal
      v-model:open="customTimePickerVisible"
      title="选择发布时间"
      width="500px"
      @ok="confirmCustomTime"
      @cancel="customTimePickerVisible = false"
    >
      <div class="custom-time-picker-content">
        <a-date-picker 
          v-model:value="formData.scheduled_time"
          show-time
          format="YYYY-MM-DD HH:mm"
          placeholder="选择精确发布时间"
          size="large"
          style="width: 100%;"
          :disabled-date="disabledDate"
          :show-now="true"
        />
        <div class="time-tips">
          <p>温馨提示</p>
          <ul>
            <li>选择的时间必须晚于当前时间</li>
            <li>建议提前设置，避免时间冲突</li>
            <li>支持精确到分钟的定时发布</li>
          </ul>
        </div>
      </div>
    </a-modal>

    <!-- 表格配置对话框 -->
    <a-modal
      v-model:open="tableConfigVisible"
      title="创建表格"
      width="450px"
      @ok="confirmCreateTable"
      @cancel="tableConfigVisible = false"
    >
      <div class="table-config-content">
        <a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
          <a-form-item label="行数">
            <a-input-number
              v-model:value="tableConfig.rows"
              :min="1"
              :max="20"
              style="width: 100%;"
              placeholder="请输入行数（1-20）"
            />
          </a-form-item>
          <a-form-item label="列数">
            <a-input-number
              v-model:value="tableConfig.cols"
              :min="1"
              :max="10"
              style="width: 100%;"
              placeholder="请输入列数（1-10）"
            />
          </a-form-item>
        </a-form>
        <div class="table-preview-hint">
          <p style="margin: 0; font-size: 13px; color: #8c8c8c;">
            💡 提示：创建后可直接点击单元格编辑内容，支持添加/删除行列、调整边框样式等操作
          </p>
        </div>
      </div>
    </a-modal>

    <!-- 预览模态框 -->
    <a-modal
      v-model:open="previewVisible"
      title="公告预览"
      width="800px"
      :footer="null"
    >
      <div class="preview-container">
        <h2>{{ formData.title }}</h2>
        <div class="preview-meta">
          <a-space>
            <a-tag :color="urgencyColorMap[formData.urgency_level]">{{ formData.urgency_level }}</a-tag>
            <span>发布范围: {{ getScopeText() }}</span>
            <span v-if="formData.validity_period && formData.validity_period.length === 2">
              有效期: {{ formData.validity_period[0].format('YYYY-MM-DD') }} ~ {{ formData.validity_period[1].format('YYYY-MM-DD') }}
            </span>
          </a-space>
        </div>
        <a-divider />
        <div class="preview-content" v-html="renderedContent"></div>
        <div v-if="fileList.length > 0" class="preview-attachments">
          <a-divider />
          <h4>附件：</h4>
          <div v-for="file in fileList" :key="file.uid">
            📎 {{ file.name }}
          </div>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, onBeforeUnmount, h } from 'vue'
import { useRouter } from 'vue-router'
import { message, Modal } from 'ant-design-vue'
import { UploadOutlined, CalendarOutlined, ClockCircleOutlined, PushpinOutlined } from '@ant-design/icons-vue'
import { announcementAPI } from '@/api/announcement'
import type { Dayjs } from 'dayjs'
import dayjs from 'dayjs'
import type { UploadProps } from 'ant-design-vue'

const router = useRouter()
const formRef = ref()
const contentEditor = ref()
const submitting = ref(false)
const savingDraft = ref(false)
const previewVisible = ref(false)
const previewTab = ref('visual')
const visualEditor = ref<HTMLElement | null>(null)
const previewArea = ref<HTMLElement | null>(null)
const isUpdatingVisualEditor = ref(false)
const uploadingImage = ref(false)
const selectedQuickTime = ref<string>('')
const isCustomTime = ref(false)
const enableScheduledTime = ref(false)
const customTimePickerVisible = ref(false)
const tableConfigVisible = ref(false)
const tableConfig = ref({ rows: 3, cols: 3 })
const currentEditingTable = ref<HTMLTableElement | null>(null)
// 当前光标所在标题级别
const currentHeadingLevel = ref<string>('')
// 当前格式状态（加粗、斜体、下划线）
const isBold = ref(false)
const isItalic = ref(false)
const isUnderline = ref(false)

// 有效期计算属性
const validityStartTime = computed({
  get: () => formData.value.validity_period?.[0],
  set: (val) => {
    if (!formData.value.validity_period) {
      formData.value.validity_period = [val, undefined as any] as [Dayjs, Dayjs]
    } else {
      formData.value.validity_period[0] = val as Dayjs
    }
  }
})

const validityEndTime = computed({
  get: () => formData.value.validity_period?.[1],
  set: (val) => {
    if (!formData.value.validity_period) {
      formData.value.validity_period = [undefined as any, val] as [Dayjs, Dayjs]
    } else {
      formData.value.validity_period[1] = val as Dayjs
    }
  }
})

// 快捷时间选项配置
const quickTimeOptions = [
  { label: '10分钟后', value: () => dayjs().add(10, 'minute') },
  { label: '30分钟后', value: () => dayjs().add(30, 'minute') },
  { label: '1小时后', value: () => dayjs().add(1, 'hour') },
  { label: '3小时后', value: () => dayjs().add(3, 'hour') },
  { label: '明天08:00', value: () => dayjs().add(1, 'day').hour(8).minute(0).second(0) },
  { label: '明天12:00', value: () => dayjs().add(1, 'day').hour(12).minute(0).second(0) },
  { label: '明天18:00', value: () => dayjs().add(1, 'day').hour(18).minute(0).second(0) },
  { label: '后天08:00', value: () => dayjs().add(2, 'day').hour(8).minute(0).second(0) },
  { label: '下周一09:00', value: () => getNextWeekday(1, 9, 0) },
  { label: '下周一14:00', value: () => getNextWeekday(1, 14, 0) },
]

// 获取下一个指定星期几的时间
const getNextWeekday = (weekday: number, hour: number, minute: number) => {
  const today = dayjs()
  const currentWeekday = today.day()
  let daysToAdd = weekday - currentWeekday
  
  // 如果目标星期已过，则跳到下周
  if (daysToAdd <= 0) {
    daysToAdd += 7
  }
  
  return today.add(daysToAdd, 'day').hour(hour).minute(minute).second(0)
}

// 切换定时发布开关
const handleScheduledTimeToggle = (checked: boolean) => {
  if (!checked) {
    // 关闭时清空时间设置
    formData.value.scheduled_time = undefined
    selectedQuickTime.value = ''
    isCustomTime.value = false
  }
}

// 选择快捷时间
const selectQuickTime = (option: typeof quickTimeOptions[0]) => {
  const time = option.value()
  
  // 检查时间是否有效（不能是过去的时间）
  if (time.isBefore(dayjs())) {
    message.warning('选择的时间不能早于当前时间')
    return
  }
  
  enableScheduledTime.value = true
  formData.value.scheduled_time = time
  selectedQuickTime.value = option.label
  isCustomTime.value = false
  
  message.success(`已设置定时发布: ${time.format('YYYY-MM-DD HH:mm')}`)
}

// 显示自定义时间选择器
const showCustomTimePicker = () => {
  enableScheduledTime.value = true
  customTimePickerVisible.value = true
}

// 格式化显示已选择的时间
const formatScheduledTime = () => {
  if (!formData.value.scheduled_time) return ''
  
  const time = formData.value.scheduled_time
  const now = dayjs()
  const diffMinutes = time.diff(now, 'minute')
  const diffHours = time.diff(now, 'hour')
  const diffDays = time.diff(now, 'day')
  
  let relativeTime = ''
  if (diffMinutes < 60) {
    relativeTime = `${diffMinutes}分钟后`
  } else if (diffHours < 24) {
    relativeTime = `${diffHours}小时后`
  } else if (diffDays === 1) {
    relativeTime = '明天'
  } else if (diffDays === 2) {
    relativeTime = '后天'
  } else {
    relativeTime = `${diffDays}天后`
  }
  
  return `${time.format('YYYY-MM-DD HH:mm')} (${relativeTime})`
}

// 清除定时发布时间
const clearScheduledTime = () => {
  formData.value.scheduled_time = undefined
  selectedQuickTime.value = ''
  isCustomTime.value = false
  enableScheduledTime.value = false
  message.info('已清除定时发布时间，将立即发布')
}

// 图片管理相关（统一数据源）
interface InsertedImage {
  id: string
  url: string
  name: string
  width: number
  height: number
  align: 'left' | 'center' | 'right'
  originalWidth: number
  originalHeight: number
}
const insertedImages = ref<InsertedImage[]>([])
const currentEditingImageId = ref<string | null>(null)
const imagePreviewVisible = ref(false)
const previewImageUrl = ref('')
const previewImageName = ref('')

// 图片尺寸预设
const IMAGE_SIZE_PRESETS = {
  small: 300,
  medium: 500,
  large: 800
} as const

// 默认显示尺寸（小尺寸，避免界面拥挤）
const DEFAULT_DISPLAY_SIZE = IMAGE_SIZE_PRESETS.small

// 存储已创建的临时 URL，用于内存管理
const tempImageUrls = ref<Set<string>>(new Set())

// 清理临时 URL
const revokeTempUrl = (url: string) => {
  if (tempImageUrls.value.has(url)) {
    URL.revokeObjectURL(url)
    tempImageUrls.value.delete(url)
  }
}

// 清理所有临时 URL
const cleanupTempUrls = () => {
  tempImageUrls.value.forEach(url => {
    URL.revokeObjectURL(url)
  })
  tempImageUrls.value.clear()
}

// 模拟用户角色（实际应从登录信息获取）
const userRole = ref<'超级管理员' | '部门管理员' | '师生用户'>('超级管理员')
const userDepartment = ref<string>('计算机学院') // 部门管理员所属部门

// 表单数据
const formData = ref({
  title: '',
  content: '',
  scope_type: '全校', // 全校、院系、年级、班级
  departments: [] as string[],
  grades: [] as string[],
  classes: [] as string[],
  urgency_level: '普通', // 普通、重要、紧急
  validity_period: undefined as [Dayjs, Dayjs] | undefined,
  scheduled_time: undefined as Dayjs | undefined,
  is_pinned: false
})

// 文件列表
const fileList = ref<any[]>([])

// 院系选项
const departmentOptions = ref([
  { id: '1', name: '计算机学院' },
  { id: '2', name: '软件学院' },
  { id: '3', name: '信息学院' },
  { id: '4', name: '数学学院' },
  { id: '5', name: '物理学院' }
])

// 年级选项
const gradeOptions = ref([
  { label: '2021级', value: '2021' },
  { label: '2022级', value: '2022' },
  { label: '2023级', value: '2023' },
  { label: '2024级', value: '2024' }
])

// 班级选项
const classOptions = ref([
  { id: '1', name: '计算机2101班' },
  { id: '2', name: '计算机2102班' },
  { id: '3', name: '软件2101班' },
  { id: '4', name: '软件2102班' }
])

// 紧急程度颜色映射
const urgencyColorMap: Record<string, string> = {
  '普通': 'default',
  '重要': 'warning',
  '紧急': 'error'
}

// 表单验证规则
const rules = {
  title: [
    { required: true, message: '请输入公告标题', trigger: 'blur' },
    { max: 100, message: '标题不能超过100个字符', trigger: 'blur' }
  ],
  content: [
    { required: true, message: '请输入公告内容', trigger: 'blur' }
  ],
  scope_type: [
    { required: true, message: '请选择发布范围', trigger: 'change' }
  ],
  urgency_level: [
    { required: true, message: '请选择紧急程度', trigger: 'change' }
  ]
}

// 增强版 Markdown 渲染（支持图片原图显示，精简HTML结构）
const renderedContent = computed(() => {
  let html = formData.value.content
  
  // 图片渲染 - 支持自定义样式属性，生成精简的 HTML
  // 格式：![alt](url){#id width=xxx height=xxx align=xxx}
  html = html.replace(
    /!\[([^\]]*)\]\(([^)]+)\)(?:\{([^}]+)\})?/g, 
    (match, alt, url, attrs) => {
      let style = 'max-width: 100%; height: auto; display: block;'
      let imageId = ''
      let align = 'left'
      
      // 解析自定义属性
      if (attrs) {
        const attrMap: Record<string, string> = {}
        attrs.split(/\s+/).forEach((attr: string) => {
          const [key, value] = attr.split('=')
          if (key && value) {
            attrMap[key] = value
          } else if (key.startsWith('#')) {
            imageId = key.substring(1)
          }
        })
        
        // 应用宽度（仅保留必要的尺寸属性）
        if (attrMap.width) {
          style += ` width: ${attrMap.width.includes('%') || attrMap.width.includes('px') ? attrMap.width : attrMap.width + 'px'};`
        }
        
        // 应用对齐方式（通过 margin 实现）
        if (attrMap.align) {
          align = attrMap.align
          if (align === 'center') {
            style += ' margin: 12px auto;'
          } else if (align === 'right') {
            style += ' margin: 12px 0 12px auto;'
          } else {
            style += ' margin: 12px 0;'
          }
        } else {
          style += ' margin: 12px 0;'
        }
        
        // 添加圆角美化
        style += ' border-radius: 4px;'
      }
      
      const idAttr = imageId ? `id="img-${imageId}"` : ''
      
      // 返回精简的 img 标签（移除 class 和不必要的容器）
      return `<img ${idAttr} src="${url}" alt="${alt}" style="${style}" />`
    }
  )
  
  // 标题
  html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>')
  html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>')
  html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>')
  
  // 粗体
  html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
  
  // 斜体（避免与图片语法冲突）
  html = html.replace(/(?<!!)\*([^*]+?)\*/g, '<em>$1</em>')
  
  // 下划线
  html = html.replace(/__(.+?)__/g, '<u>$1</u>')
  
  // 列表
  html = html.replace(/^- (.+)$/gm, '<li>$1</li>')
  html = html.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>')
  
  // 表格支持
  html = renderMarkdownTable(html)
  
  // 换行
  html = html.replace(/\n/g, '<br>')
  
  return html
})

// 渲染 Markdown 表格
const renderMarkdownTable = (html: string): string => {
  const tableRegex = /\|(.+)\|\n\|([\s\S]+?)\|\n((?:\|.+\|\n?)+)/g
  return html.replace(tableRegex, (match, header, separator, rows) => {
    const headers = header.split('|').map((h: string) => h.trim()).filter(Boolean)
    const rowsArray = rows.trim().split('\n').map((row: string) => 
      row.split('|').map((cell: string) => cell.trim()).filter(Boolean)
    )
    
    let table = '<table border="1" style="border-collapse: collapse; width: 100%; margin: 12px 0;">'
    table += '<thead><tr>'
    headers.forEach((h: string) => {
      table += `<th style="border: 1px solid #d9d9d9; padding: 8px 12px; background: #fafafa;">${h}</th>`
    })
    table += '</tr></thead><tbody>'
    
    rowsArray.forEach((row: string[]) => {
      table += '<tr>'
      row.forEach((cell: string) => {
        table += `<td style="border: 1px solid #d9d9d9; padding: 8px 12px;">${cell}</td>`
      })
      table += '</tr>'
    })
    
    table += '</tbody></table>'
    return table
  })
}

// 禁用过去的日期
const disabledDate = (current: Dayjs) => {
  return current && current < dayjs().startOf('day')
}

// 发布范围变更
const handleScopeTypeChange = () => {
  formData.value.departments = []
  formData.value.grades = []
  formData.value.classes = []
}

// 获取范围文本
const getScopeText = () => {
  const { scope_type, departments, grades, classes } = formData.value
  
  if (scope_type === '全校') return '全校'
  if (scope_type === '院系') {
    const names = departments.map(id => 
      departmentOptions.value.find(d => d.id === id)?.name
    ).filter(Boolean)
    return names.length > 0 ? names.join('、') : '未选择'
  }
  if (scope_type === '年级') {
    const names = grades.map(value => 
      gradeOptions.value.find(g => g.value === value)?.label
    ).filter(Boolean)
    return names.length > 0 ? names.join('、') : '未选择'
  }
  if (scope_type === '班级') {
    const names = classes.map(id => 
      classOptions.value.find(c => c.id === id)?.name
    ).filter(Boolean)
    return names.length > 0 ? names.join('、') : '未选择'
  }
  return ''
}

// 富文本编辑功能（基于可视化编辑器）
const insertBold = () => {
  const editor = visualEditor.value
  if (!editor) return
  
  editor.focus()
  document.execCommand('bold', false)
  
  // 更新格式状态
  setTimeout(() => {
    updateFormatStates()
    if (editor) {
      formData.value.content = editor.innerHTML
    }
  }, 50)
}

const insertItalic = () => {
  const editor = visualEditor.value
  if (!editor) return
  
  editor.focus()
  document.execCommand('italic', false)
  
  // 更新格式状态
  setTimeout(() => {
    updateFormatStates()
    if (editor) {
      formData.value.content = editor.innerHTML
    }
  }, 50)
}

const insertUnderline = () => {
  const editor = visualEditor.value
  if (!editor) return
  
  editor.focus()
  document.execCommand('underline', false)
  
  // 更新格式状态
  setTimeout(() => {
    updateFormatStates()
    if (editor) {
      formData.value.content = editor.innerHTML
    }
  }, 50)
}

// 标题样式配置 - 适配校园公告场景
const headingStyles = {
  large: {
    fontSize: '18px',
    fontWeight: 'bold',
    color: '#333',
    borderBottom: '1px solid #e8e8e8',
    paddingBottom: '8px',
    marginTop: '20px',
    marginBottom: '16px',
    lineHeight: '1.5',
    label: '大标题'
  },
  medium: {
    fontSize: '16px',
    fontWeight: 'bold',
    color: '#444',
    marginTop: '16px',
    marginBottom: '12px',
    lineHeight: '1.5',
    label: '中标题'
  },
  small: {
    fontSize: '15px',
    fontWeight: 'normal',
    color: '#1A365D',
    marginTop: '12px',
    marginBottom: '10px',
    lineHeight: '1.5',
    label: '小标题'
  }
} as const

// 标题功能 - 一键切换，整行生效
const toggleHeading = (level: 'large' | 'medium' | 'small') => {
  const editor = visualEditor.value
  if (!editor) return
  
  editor.focus()
  
  const selection = window.getSelection()
  if (!selection || selection.rangeCount === 0) return
  
  // 获取当前光标所在的块元素
  let currentBlock = getCurrentBlock(selection)
  if (!currentBlock) {
    // 如果没有找到块元素，创建一个新的
    currentBlock = createNewTextBlock()
    if (selection.rangeCount > 0) {
      const range = selection.getRangeAt(0)
      range.insertNode(currentBlock)
    } else {
      editor.appendChild(currentBlock)
    }
  }
  
  // 检查是否已是同级别标题，是则恢复为普通文本
  if (currentBlock.dataset.headingLevel === level) {
    convertToNormalText(currentBlock)
    currentHeadingLevel.value = ''
    handleVisualEditorInput()
    return
  }
  
  // 应用新标题样式
  applyHeadingToBlock(currentBlock, level)
  currentHeadingLevel.value = level
  handleVisualEditorInput()
  
  // 光标移到行尾
  const range = document.createRange()
  range.selectNodeContents(currentBlock)
  range.collapse(false)
  selection.removeAllRanges()
  selection.addRange(range)
}

// 获取当前光标所在的块元素
const getCurrentBlock = (selection: Selection): HTMLElement | null => {
  const range = selection.getRangeAt(0)
  let node: Node | null = range.commonAncestorContainer
  
  // 如果是文本节点，获取其父元素
  if (node.nodeType === Node.TEXT_NODE) {
    node = node.parentElement
  }
  
  // 查找最近的块级元素
  while (node && node !== visualEditor.value) {
    if ((node as HTMLElement).classList?.contains('text-content-block') ||
        (node as HTMLElement).classList?.contains('heading-style')) {
      return node as HTMLElement
    }
    node = node.parentElement
  }
  
  return null
}

// 创建新的文本块
const createNewTextBlock = (): HTMLElement => {
  const block = document.createElement('div')
  block.className = 'text-content-block'
  block.contentEditable = 'true'
  block.style.cssText = 'margin: 0 0 12px 0; font-size: 14px; color: #666; line-height: 1.8;'
  block.innerHTML = '<br>'
  return block
}

// 应用标题样式到块元素
const applyHeadingToBlock = (block: HTMLElement, level: 'large' | 'medium' | 'small') => {
  const style = headingStyles[level]
  
  // 设置标题类和数据属性
  block.className = 'heading-style text-content-block'
  block.dataset.headingLevel = level
  block.contentEditable = 'true'
  
  // 应用样式
  let cssText = `
    font-size: ${style.fontSize};
    font-weight: ${style.fontWeight};
    color: ${style.color};
    margin-top: ${style.marginTop};
    margin-bottom: ${style.marginBottom};
    line-height: ${style.lineHeight};
    display: block;
    width: 100%;
  `
  
  if (level === 'large') {
    cssText += `
      border-bottom: ${style.borderBottom};
      padding-bottom: ${style.paddingBottom};
    `
  }
  
  block.style.cssText = cssText
}

// 将标题转换为普通文本
const convertToNormalText = (block: HTMLElement) => {
  block.className = 'text-content-block'
  delete block.dataset.headingLevel
  block.contentEditable = 'true'
  block.style.cssText = 'margin: 0 0 12px 0; font-size: 14px; color: #666; line-height: 1.8;'
}

// 更新当前标题级别状态（光标移动时）
const updateCurrentHeadingLevel = () => {
  const selection = window.getSelection()
  if (!selection || selection.rangeCount === 0) {
    currentHeadingLevel.value = ''
    return
  }
  
  const currentBlock = getCurrentBlock(selection)
  if (currentBlock && currentBlock.dataset.headingLevel) {
    currentHeadingLevel.value = currentBlock.dataset.headingLevel
  } else {
    currentHeadingLevel.value = ''
  }
  
  // 同时更新格式状态
  updateFormatStates()
}

// 更新格式状态（加粗、斜体、下划线）
const updateFormatStates = () => {
  const selection = window.getSelection()
  if (!selection || selection.rangeCount === 0) {
    isBold.value = false
    isItalic.value = false
    isUnderline.value = false
    return
  }
  
  // 使用 queryCommandState 检测当前格式状态
  try {
    isBold.value = document.queryCommandState('bold')
    isItalic.value = document.queryCommandState('italic')
    isUnderline.value = document.queryCommandState('underline')
  } catch (e) {
    // 降级方案：手动检测父元素
    const range = selection.getRangeAt(0)
    let node: Node | null = range.commonAncestorContainer
    
    if (node.nodeType === Node.TEXT_NODE) {
      node = node.parentElement
    }
    
    isBold.value = false
    isItalic.value = false
    isUnderline.value = false
    
    // 向上遍历检测格式标签
    while (node && node !== visualEditor.value) {
      const tagName = (node as HTMLElement).tagName?.toLowerCase()
      const style = (node as HTMLElement).style
      
      if (tagName === 'strong' || tagName === 'b' || style?.fontWeight === 'bold') {
        isBold.value = true
      }
      if (tagName === 'em' || tagName === 'i' || style?.fontStyle === 'italic') {
        isItalic.value = true
      }
      if (tagName === 'u' || style?.textDecoration?.includes('underline')) {
        isUnderline.value = true
      }
      
      node = node.parentElement
    }
  }
}

// 插入无序列表
const insertList = () => {
  insertInteractiveList('ul')
}

// 插入有序列表
const insertOrderedList = () => {
  insertInteractiveList('ol')
}

// 插入可交互列表（新版）
const insertInteractiveList = (listType: 'ul' | 'ol') => {
  const editor = visualEditor.value
  if (!editor) return
  
  editor.focus()
  
  const selection = window.getSelection()
  if (!selection) return
  
  // 创建列表元素
  const listElement = document.createElement(listType)
  listElement.className = 'interactive-list'
  listElement.style.cssText = 'margin: 12px 0; padding-left: 24px; list-style-position: outside;'
  
  // 创建第一个列表项
  const firstItem = document.createElement('li')
  firstItem.style.cssText = 'margin: 6px 0; padding: 4px 8px; min-height: 24px; cursor: text;'
  firstItem.contentEditable = 'true'
  firstItem.innerHTML = '输入内容...'
  
  listElement.appendChild(firstItem)
  
  // 插入到编辑器
  if (selection.rangeCount > 0) {
    const range = selection.getRangeAt(0)
    range.deleteContents()
    range.insertNode(listElement)
    
    // 设置光标到第一个列表项
    range.setStart(firstItem, 0)
    range.setEnd(firstItem, firstItem.childNodes.length)
    selection.removeAllRanges()
    selection.addRange(range)
  } else {
    editor.appendChild(listElement)
    firstItem.focus()
  }
  
  // 绑定列表交互事件
  makeListInteractive(listElement)
  
  handleVisualEditorInput()
}

// 使列表可交互（支持回车自动创建下一项、嵌套等）
const makeListInteractive = (listElement: HTMLElement) => {
  const listItems = listElement.querySelectorAll('li')
  
  listItems.forEach((item) => {
    // 确保列表项可编辑
    if (!item.hasAttribute('contenteditable')) {
      item.contentEditable = 'true'
    }
    
    // 回车事件：自动创建下一项
    item.addEventListener('keydown', (e: KeyboardEvent) => {
      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault()
        
        const currentItem = e.target as HTMLElement
        const parentList = currentItem.parentElement
        
        // 如果当前项为空，则退出列表
        if (currentItem.textContent?.trim() === '' || currentItem.textContent === '输入内容...') {
          // 删除当前空项
          currentItem.remove()
          
          // 将光标移到列表外
          const editor = visualEditor.value
          if (editor && parentList) {
            const newParagraph = document.createElement('div')
            newParagraph.className = 'text-content-block'
            newParagraph.innerHTML = '<br>'
            newParagraph.contentEditable = 'true'
            parentList.after(newParagraph)
            
            // 设置光标到新段落
            const range = document.createRange()
            const selection = window.getSelection()
            range.setStart(newParagraph, 0)
            range.collapse(true)
            selection?.removeAllRanges()
            selection?.addRange(range)
            newParagraph.focus()
          }
          
          handleVisualEditorInput()
          return
        }
        
        // 创建新列表项
        const newItem = document.createElement('li')
        newItem.style.cssText = currentItem.style.cssText
        newItem.contentEditable = 'true'
        newItem.innerHTML = '<br>' // 使用 <br> 确保光标可定位
        
        // 插入到当前项后面
        currentItem.after(newItem)
        
        // 精准设置光标到新项开头
        const range = document.createRange()
        const selection = window.getSelection()
        range.setStart(newItem, 0)
        range.collapse(true)
        selection?.removeAllRanges()
        selection?.addRange(range)
        newItem.focus()
        
        // 绑定新项的事件
        makeListInteractive(parentList as HTMLElement)
        
        handleVisualEditorInput()
      }
      
      // Tab键：增加嵌套层级
      if (e.key === 'Tab' && !e.shiftKey) {
        e.preventDefault()
        
        const currentItem = e.target as HTMLElement
        const prevItem = currentItem.previousElementSibling
        
        if (!prevItem) return
        
        // 获取父列表类型
        const parentListType = currentItem.parentElement?.tagName.toLowerCase()
        
        // 查找或创建嵌套列表（切换类型：ul -> ol 或 ol -> ul）
        let nestedList = prevItem.querySelector(':scope > ul, :scope > ol') as HTMLElement
        
        if (!nestedList) {
          // 创建嵌套列表（与父列表类型相反）
          const nestedType = parentListType === 'ul' ? 'ol' : 'ul'
          nestedList = document.createElement(nestedType)
          nestedList.className = 'interactive-list nested'
          nestedList.style.cssText = 'margin: 6px 0; padding-left: 24px; list-style-position: outside;'
          prevItem.appendChild(nestedList)
        }
        
        // 保存当前光标位置内容
        const savedContent = currentItem.innerHTML
        
        // 移动当前项到嵌套列表
        currentItem.remove()
        nestedList.appendChild(currentItem)
        
        // 恢复内容并聚焦
        currentItem.innerHTML = savedContent
        const range = document.createRange()
        const selection = window.getSelection()
        range.selectNodeContents(currentItem)
        range.collapse(false)
        selection?.removeAllRanges()
        selection?.addRange(range)
        currentItem.focus()
        
        handleVisualEditorInput()
      }
      
      // Shift+Tab：减少嵌套层级
      if (e.key === 'Tab' && e.shiftKey) {
        e.preventDefault()
        
        const currentItem = e.target as HTMLElement
        const parentList = currentItem.parentElement
        const grandParentItem = parentList?.parentElement?.closest('li')
        
        if (!grandParentItem) return
        
        // 保存当前光标位置内容
        const savedContent = currentItem.innerHTML
        
        // 移动当前项到父级列表
        currentItem.remove()
        grandParentItem.after(currentItem)
        
        // 恢复内容并聚焦
        currentItem.innerHTML = savedContent
        const range = document.createRange()
        const selection = window.getSelection()
        range.selectNodeContents(currentItem)
        range.collapse(false)
        selection?.removeAllRanges()
        selection?.addRange(range)
        currentItem.focus()
        
        // 如果嵌套列表为空，删除它
        if (parentList && parentList.children.length === 0) {
          parentList.remove()
        }
        
        handleVisualEditorInput()
      }
    })
    
    // 点击列表项时精准定位光标
    item.addEventListener('click', (e: MouseEvent) => {
      e.stopPropagation()
      const target = e.target as HTMLElement
      
      // 使用 caretRangeFromPoint 精准定位光标
      try {
        const range = document.caretRangeFromPoint(e.clientX, e.clientY)
        if (range && item.contains(range.startContainer)) {
          const selection = window.getSelection()
          selection?.removeAllRanges()
          selection?.addRange(range)
        }
      } catch (err) {
        // 降级方案：设置到点击位置
        target.focus()
      }
    })
    
    // 失去焦点时移除占位符
    item.addEventListener('focus', (e: FocusEvent) => {
      const target = e.target as HTMLElement
      if (target.textContent === '输入内容...') {
        target.textContent = ''
      }
    })
    
    item.addEventListener('blur', (e: FocusEvent) => {
      const target = e.target as HTMLElement
      if (target.textContent?.trim() === '') {
        target.innerHTML = '<br>' // 使用 <br> 保持可编辑状态
        target.style.color = '#bfbfbf'
      } else {
        target.style.color = ''
      }
    })
  })
}

// 显示表格配置对话框
const insertTable = () => {
  tableConfigVisible.value = true
  tableConfig.value = { rows: 3, cols: 3 }
}

// 确认创建表格
const confirmCreateTable = () => {
  const { rows, cols } = tableConfig.value
  
  if (rows < 1 || rows > 20 || cols < 1 || cols > 10) {
    message.warning('行数范围：1-20，列数范围：1-10')
    return
  }
  
  const editor = visualEditor.value
  if (!editor) return
  
  // 创建表格元素
  const tableWrapper = document.createElement('div')
  tableWrapper.className = 'interactive-table-wrapper'
  tableWrapper.style.cssText = 'margin: 16px 0; position: relative; overflow-x: auto;'
  
  const table = document.createElement('table')
  table.className = 'interactive-table'
  table.style.cssText = `
    border-collapse: collapse;
    width: 100%;
    border: 2px solid #d9d9d9;
    background: #fff;
  `
  
  // 创建表头
  const thead = document.createElement('thead')
  const headerRow = document.createElement('tr')
  
  for (let i = 0; i < cols; i++) {
    const th = document.createElement('th')
    th.contentEditable = 'true'
    th.style.cssText = `
      border: 1px solid #d9d9d9;
      padding: 10px 12px;
      background: #fafafa;
      font-weight: 600;
      text-align: left;
      min-width: 100px;
      cursor: text;
    `
    th.innerHTML = `列 ${i + 1}` // 使用 innerHTML 确保可编辑
    
    // 绑定单元格光标定位事件
    bindCellEvents(th)
    
    headerRow.appendChild(th)
  }
  
  thead.appendChild(headerRow)
  table.appendChild(thead)
  
  // 创建表体
  const tbody = document.createElement('tbody')
  
  for (let i = 0; i < rows; i++) {
    const row = document.createElement('tr')
    
    for (let j = 0; j < cols; j++) {
      const td = document.createElement('td')
      td.contentEditable = 'true'
      td.style.cssText = `
        border: 1px solid #d9d9d9;
        padding: 10px 12px;
        min-width: 100px;
        cursor: text;
      `
      td.innerHTML = '<br>' // 使用 <br> 确保单元格可编辑
      
      // 绑定单元格光标定位事件
      bindCellEvents(td)
      
      row.appendChild(td)
    }
    
    tbody.appendChild(row)
  }
  
  table.appendChild(tbody)
  tableWrapper.appendChild(table)
  
  // 插入到编辑器
  editor.focus()
  const selection = window.getSelection()
  
  if (selection && selection.rangeCount > 0) {
    const range = selection.getRangeAt(0)
    range.deleteContents()
    range.insertNode(tableWrapper)
    
    // 将光标移到表格后
    const br = document.createElement('br')
    tableWrapper.after(br)
    range.setStartAfter(br)
    range.collapse(true)
    selection.removeAllRanges()
    selection.addRange(range)
  } else {
    editor.appendChild(tableWrapper)
  }
  
  // 使表格可交互
  makeTableInteractive(tableWrapper)
  
  handleVisualEditorInput()
  tableConfigVisible.value = false
  
  message.success(`已插入 ${rows} 行 ${cols} 列表格`)
}

// 绑定表格单元格事件（光标定位、Tab/Enter 键导航）
const bindCellEvents = (cell: HTMLTableCellElement) => {
  // 点击单元格时精准定位光标
  cell.addEventListener('click', (e: MouseEvent) => {
    e.stopPropagation()
    
    // 使用 caretRangeFromPoint 精准定位光标到点击位置
    try {
      const range = document.caretRangeFromPoint(e.clientX, e.clientY)
      if (range && cell.contains(range.startContainer)) {
        const selection = window.getSelection()
        selection?.removeAllRanges()
        selection?.addRange(range)
      } else {
        throw new Error('Range not in cell')
      }
    } catch (err) {
      // 降级方案：设置光标到单元格开头
      const range = document.createRange()
      const selection = window.getSelection()
      range.setStart(cell, 0)
      range.collapse(true)
      selection?.removeAllRanges()
      selection?.addRange(range)
    }
    
    cell.focus()
  })
  
  // Tab 键切换到下一列，Shift+Tab 切换到上一列
  cell.addEventListener('keydown', (e: KeyboardEvent) => {
    if (e.key === 'Tab') {
      e.preventDefault()
      
      const currentCell = e.target as HTMLTableCellElement
      const row = currentCell.parentElement as HTMLTableRowElement
      const table = row.closest('table') as HTMLTableElement
      
      if (!table) return
      
      const cells = Array.from(row.cells)
      const currentIndex = cells.indexOf(currentCell)
      
      if (e.shiftKey) {
        // Shift+Tab: 移动到上一列
        if (currentIndex > 0) {
          const prevCell = cells[currentIndex - 1]
          focusCell(prevCell)
        } else {
          // 如果是第一列，移动到上一行的最后一列
          const rows = Array.from(table.querySelectorAll('tr'))
          const rowIndex = rows.indexOf(row)
          if (rowIndex > 0) {
            const prevRow = rows[rowIndex - 1]
            const lastCell = prevRow.cells[prevRow.cells.length - 1]
            focusCell(lastCell)
          }
        }
      } else {
        // Tab: 移动到下一列
        if (currentIndex < cells.length - 1) {
          const nextCell = cells[currentIndex + 1]
          focusCell(nextCell)
        } else {
          // 如果是最后一列，移动到下一行的第一列
          const rows = Array.from(table.querySelectorAll('tr'))
          const rowIndex = rows.indexOf(row)
          if (rowIndex < rows.length - 1) {
            const nextRow = rows[rowIndex + 1]
            const firstCell = nextRow.cells[0]
            focusCell(firstCell)
          }
        }
      }
    }
    
    // Enter 键切换到下一行的同列
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      
      const currentCell = e.target as HTMLTableCellElement
      const row = currentCell.parentElement as HTMLTableRowElement
      const table = row.closest('table') as HTMLTableElement
      
      if (!table) return
      
      const cells = Array.from(row.cells)
      const currentIndex = cells.indexOf(currentCell)
      const rows = Array.from(table.querySelectorAll('tr'))
      const rowIndex = rows.indexOf(row)
      
      if (rowIndex < rows.length - 1) {
        const nextRow = rows[rowIndex + 1]
        const nextCell = nextRow.cells[currentIndex]
        if (nextCell) {
          focusCell(nextCell)
        }
      }
    }
  })
}

// 聚焦单元格并设置光标到开头
const focusCell = (cell: HTMLTableCellElement) => {
  const range = document.createRange()
  const selection = window.getSelection()
  
  // 设置光标到单元格内容开头
  if (cell.childNodes.length > 0) {
    range.setStart(cell.childNodes[0], 0)
  } else {
    range.setStart(cell, 0)
  }
  range.collapse(true)
  selection?.removeAllRanges()
  selection?.addRange(range)
  cell.focus()
}

// 使表格可交互（显示工具栏、支持编辑）
const makeTableInteractive = (tableWrapper: HTMLElement) => {
  const table = tableWrapper.querySelector('table') as HTMLTableElement
  if (!table) return
  
  // 为所有现有单元格绑定事件
  const allCells = table.querySelectorAll('th, td')
  allCells.forEach(cell => {
    bindCellEvents(cell as HTMLTableCellElement)
  })
  
  // 创建工具栏
  let toolbar = tableWrapper.querySelector('.table-toolbar') as HTMLElement
  
  if (!toolbar) {
    toolbar = document.createElement('div')
    toolbar.className = 'table-toolbar'
    toolbar.style.cssText = `
      position: absolute;
      top: -42px;
      left: 0;
      display: none;
      gap: 6px;
      padding: 6px 10px;
      background: rgba(255, 255, 255, 0.98);
      border: 1px solid #d9d9d9;
      border-radius: 6px;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
      z-index: 100;
      align-items: center;
      flex-wrap: wrap;
    `
    
    // 工具栏按钮
    const buttons = [
      { label: '➕ 插入行（上）', action: () => insertTableRow(table, 'before') },
      { label: '➕ 插入行（下）', action: () => insertTableRow(table, 'after') },
      { label: '➕ 插入列（左）', action: () => insertTableColumn(table, 'before') },
      { label: '➕ 插入列（右）', action: () => insertTableColumn(table, 'after') },
      { label: '🗑️ 删除行', action: () => deleteTableRow(table) },
      { label: '🗑️ 删除列', action: () => deleteTableColumn(table) },
      { label: '🎨 边框样式', action: () => toggleTableBorder(table) },
      { label: '❌ 删除表格', action: () => deleteTable(tableWrapper), danger: true }
    ]
    
    buttons.forEach(btn => {
      const button = document.createElement('button')
      button.textContent = btn.label
      button.className = 'table-toolbar-btn'
      button.style.cssText = `
        padding: 6px 12px;
        border: 1px solid ${btn.danger ? '#ff4d4f' : '#d9d9d9'};
        border-radius: 4px;
        background: ${btn.danger ? '#fff1f0' : '#fff'};
        color: ${btn.danger ? '#ff4d4f' : '#262626'};
        font-size: 12px;
        cursor: pointer;
        transition: all 0.3s;
        white-space: nowrap;
      `
      
      button.addEventListener('mouseenter', () => {
        button.style.borderColor = btn.danger ? '#ff4d4f' : '#1890ff'
        button.style.background = btn.danger ? '#ffccc7' : '#e6f7ff'
        button.style.transform = 'translateY(-1px)'
      })
      
      button.addEventListener('mouseleave', () => {
        button.style.borderColor = btn.danger ? '#ff4d4f' : '#d9d9d9'
        button.style.background = btn.danger ? '#fff1f0' : '#fff'
        button.style.transform = 'translateY(0)'
      })
      
      button.addEventListener('click', (e) => {
        e.stopPropagation()
        btn.action()
      })
      
      toolbar.appendChild(button)
    })
    
    tableWrapper.insertBefore(toolbar, table)
  }
  
  // 点击表格显示工具栏
  table.addEventListener('click', (e) => {
    e.stopPropagation()
    currentEditingTable.value = table
    toolbar.style.display = 'flex'
  })
  
  // 点击编辑器其他地方隐藏工具栏
  document.addEventListener('click', (e) => {
    if (!tableWrapper.contains(e.target as Node)) {
      toolbar.style.display = 'none'
    }
  })
}

// 插入表格行
const insertTableRow = (table: HTMLTableElement, position: 'before' | 'after') => {
  const selection = window.getSelection()
  const activeCell = selection?.focusNode?.parentElement
  
  if (!activeCell || (!activeCell.matches('td') && !activeCell.matches('th'))) {
    message.warning('请先选中一个单元格')
    return
  }
  
  const currentRow = activeCell.closest('tr') as HTMLTableRowElement
  const colCount = currentRow.cells.length
  
  const newRow = document.createElement('tr')
  
  for (let i = 0; i < colCount; i++) {
    const td = document.createElement('td')
    td.contentEditable = 'true'
    td.style.cssText = `
      border: 1px solid #d9d9d9;
      padding: 10px 12px;
      min-width: 100px;
      cursor: text;
    `
    td.innerHTML = '<br>' // 使用 <br> 确保可编辑
    
    // 绑定单元格事件
    bindCellEvents(td as HTMLTableCellElement)
    
    newRow.appendChild(td)
  }
  
  if (position === 'before') {
    currentRow.before(newRow)
  } else {
    currentRow.after(newRow)
  }
  
  handleVisualEditorInput()
  message.success('已插入新行')
}

// 插入表格列
const insertTableColumn = (table: HTMLTableElement, position: 'before' | 'after') => {
  const selection = window.getSelection()
  const activeCell = selection?.focusNode?.parentElement
  
  if (!activeCell || (!activeCell.matches('td') && !activeCell.matches('th'))) {
    message.warning('请先选中一个单元格')
    return
  }
  
  const cellIndex = Array.from(activeCell.parentElement!.children).indexOf(activeCell)
  const rows = table.querySelectorAll('tr')
  
  rows.forEach((row, index) => {
    const newCell = document.createElement(index === 0 ? 'th' : 'td')
    newCell.contentEditable = 'true'
    newCell.style.cssText = index === 0
      ? `
        border: 1px solid #d9d9d9;
        padding: 10px 12px;
        background: #fafafa;
        font-weight: 600;
        text-align: left;
        min-width: 100px;
        cursor: text;
      `
      : `
        border: 1px solid #d9d9d9;
        padding: 10px 12px;
        min-width: 100px;
        cursor: text;
      `
    newCell.innerHTML = '<br>' // 使用 <br> 确保可编辑
    
    // 绑定单元格事件
    bindCellEvents(newCell as HTMLTableCellElement)
    
    const targetCell = row.cells[cellIndex]
    if (position === 'before') {
      targetCell.before(newCell)
    } else {
      targetCell.after(newCell)
    }
  })
  
  handleVisualEditorInput()
  message.success('已插入新列')
}

// ========================================
// 内容一致性检查与自动修复
// ========================================

// 定期检查内容一致性（防止意外不同步）
let consistencyCheckTimer: number | null = null

const startConsistencyCheck = () => {
  stopConsistencyCheck()
  
  consistencyCheckTimer = window.setInterval(() => {
    if (visualEditor.value && previewArea.value && previewTab.value === 'preview') {
      const isValid = validateContentSync(
        visualEditor.value.innerHTML,
        previewArea.value.innerHTML
      )
      
      if (!isValid) {
        console.warn('⚠️ 检测到内容漂移，触发自动修复')
        autoFixContentSync()
      }
    }
  }, 3000) // 每3秒检查一次
}

const stopConsistencyCheck = () => {
  if (consistencyCheckTimer) {
    clearInterval(consistencyCheckTimer)
    consistencyCheckTimer = null
  }
}

// 手动触发一致性检查（用于调试）
const manualCheckConsistency = () => {
  if (!visualEditor.value || !previewArea.value) {
    message.warning('编辑器未初始化')
    return
  }
  
  const isValid = logContentDiff(
    visualEditor.value.innerHTML,
    previewArea.value.innerHTML
  )
  
  if (isValid) {
    message.success('✅ 内容完全一致')
  } else {
    message.error('❌ 检测到内容不一致，已触发自动修复')
    autoFixContentSync()
  }
}

// 删除表格行
const deleteTableRow = (table: HTMLTableElement) => {
  const selection = window.getSelection()
  const activeCell = selection?.focusNode?.parentElement
  
  if (!activeCell || (!activeCell.matches('td') && !activeCell.matches('th'))) {
    message.warning('请先选中一个单元格')
    return
  }
  
  const currentRow = activeCell.closest('tr') as HTMLTableRowElement
  const tbody = currentRow.parentElement
  
  // 防止删除最后一行
  if (tbody && tbody.children.length <= 1) {
    message.warning('至少保留一行')
    return
  }
  
  currentRow.remove()
  handleVisualEditorInput()
  message.success('已删除该行')
}

// 删除表格列
const deleteTableColumn = (table: HTMLTableElement) => {
  const selection = window.getSelection()
  const activeCell = selection?.focusNode?.parentElement
  
  if (!activeCell || (!activeCell.matches('td') && !activeCell.matches('th'))) {
    message.warning('请先选中一个单元格')
    return
  }
  
  const cellIndex = Array.from(activeCell.parentElement!.children).indexOf(activeCell)
  const rows = table.querySelectorAll('tr')
  
  // 防止删除最后一列
  if (rows[0] && rows[0].cells.length <= 1) {
    message.warning('至少保留一列')
    return
  }
  
  rows.forEach(row => {
    row.cells[cellIndex]?.remove()
  })
  
  handleVisualEditorInput()
  message.success('已删除该列')
}

// 切换表格边框样式
const toggleTableBorder = (table: HTMLTableElement) => {
  const currentBorder = table.style.border
  
  if (currentBorder.includes('2px solid #d9d9d9')) {
    table.style.border = '3px double #1890ff'
    message.success('已切换为双线边框')
  } else if (currentBorder.includes('3px double')) {
    table.style.border = '2px dashed #52c41a'
    message.success('已切换为虚线边框')
  } else {
    table.style.border = '2px solid #d9d9d9'
    message.success('已切换为实线边框')
  }
  
  handleVisualEditorInput()
}

// 删除整个表格
const deleteTable = (tableWrapper: HTMLElement) => {
  Modal.confirm({
    title: '确认删除表格？',
    content: '此操作不可撤销',
    okText: '确认删除',
    okType: 'danger',
    cancelText: '取消',
    onOk: () => {
      tableWrapper.remove()
      handleVisualEditorInput()
      message.success('表格已删除')
    }
  })
}

// 在光标位置插入文本（可视化编辑器）
const insertTextAtCursor = (text: string) => {
  const editor = visualEditor.value
  if (!editor) return
  
  editor.focus()
  
  const selection = window.getSelection()
  if (!selection || selection.rangeCount === 0) {
    // 没有选区，查找或创建可编辑的文本容器
    let textContainer = editor.querySelector('.text-content-block')
    
    if (!textContainer) {
      textContainer = document.createElement('div')
      textContainer.className = 'text-content-block'
      editor.insertBefore(textContainer, editor.firstChild)
    }
    
    const textNode = document.createTextNode(text)
    textContainer.appendChild(textNode)
    
    // 设置光标
    const range = document.createRange()
    range.setStartAfter(textNode)
    range.collapse(true)
    selection.removeAllRanges()
    selection.addRange(range)
  } else {
    // 在当前光标位置插入
    const range = selection.getRangeAt(0)
    
    // 检查是否在图片容器内，如果是则移到容器外
    let container = range.startContainer
    if (container.nodeType === Node.ELEMENT_NODE) {
      const elem = container as HTMLElement
      const imageBlock = elem.closest('.image-container-block, .image-wrapper-interactive')
      if (imageBlock) {
        // 在图片后插入文本
        let textContainer = imageBlock.nextElementSibling
        if (!textContainer || !textContainer.classList.contains('text-content-block')) {
          textContainer = document.createElement('div')
          textContainer.className = 'text-content-block'
          imageBlock.after(textContainer)
        }
        
        const textNode = document.createTextNode(text)
        textContainer.appendChild(textNode)
        
        range.setStartAfter(textNode)
        range.collapse(true)
        selection.removeAllRanges()
        selection.addRange(range)
        
        handleVisualEditorInput()
        return
      }
    }
    
    // 正常插入
    range.deleteContents()
    const textNode = document.createTextNode(text)
    range.insertNode(textNode)
    
    range.setStartAfter(textNode)
    range.collapse(true)
    selection.removeAllRanges()
    selection.addRange(range)
  }
  
  handleVisualEditorInput()
}

// 图片上传并插入原图（基于统一数据源）
const handleImageUpload = async (file: File) => {
  const isImage = file.type.startsWith('image/')
  if (!isImage) {
    message.error('只能上传图片文件')
    return false
  }
  
  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    message.error('图片大小不能超过 10MB')
    return false
  }
  
  uploadingImage.value = true
  
  try {
    // 创建图片对象以获取原始尺寸
    const img = new Image()
    const imageUrl = URL.createObjectURL(file)
    
    // 记录临时 URL
    tempImageUrls.value.add(imageUrl)
    
    // 等待图片加载完成以获取原始尺寸
    await new Promise((resolve, reject) => {
      img.onload = resolve
      img.onerror = reject
      img.src = imageUrl
    })
    
    // 生成唯一ID
    const imageId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
    
    // 获取图片原始尺寸
    const originalWidth = img.naturalWidth
    const originalHeight = img.naturalHeight
    
    // 默认使用小尺寸（300px），避免界面拥挤
    const defaultWidth = DEFAULT_DISPLAY_SIZE
    let displayWidth = defaultWidth
    let displayHeight = Math.round((originalHeight * defaultWidth) / originalWidth)
    
    // 如果原图比默认尺寸小，则使用原图尺寸（保持清晰度）
    if (originalWidth < defaultWidth) {
      displayWidth = originalWidth
      displayHeight = originalHeight
    }
    
    // TODO: 实际应上传到服务器
    const uploadedUrl = imageUrl
    
    // 添加到统一数据源
    const imageInfo: InsertedImage = {
      id: imageId,
      url: uploadedUrl,
      name: file.name,
      width: displayWidth,
      height: displayHeight,
      align: 'center',
      originalWidth,
      originalHeight
    }
    insertedImages.value.push(imageInfo)
    
    // 直接插入图片到编辑区的光标位置（或末尾）
    if (visualEditor.value) {
      const selection = window.getSelection()
      const imageHtml = renderImageFromSource(imageInfo, true)
      
      if (selection && selection.rangeCount > 0 && visualEditor.value.contains(selection.anchorNode)) {
        // 在光标位置插入图片
        const range = selection.getRangeAt(0)
        range.deleteContents()
        
        const tempDiv = document.createElement('div')
        tempDiv.innerHTML = imageHtml
        const imageNode = tempDiv.firstChild
        
        if (imageNode) {
          range.insertNode(imageNode)
          
          // 在图片后添加一个可编辑的文本块（确保用户可以继续输入）
          const editableBlock = document.createElement('div')
          editableBlock.className = 'text-content-block'
          editableBlock.contentEditable = 'true'
          editableBlock.style.cssText = 'margin: 0 0 12px 0; font-size: 14px; color: #666; line-height: 1.8; min-height: 20px;'
          editableBlock.innerHTML = '<br>' // 空行占位
          
          range.setStartAfter(imageNode)
          range.collapse(true)
          range.insertNode(editableBlock)
          
          // 将光标移到新文本块
          range.setStart(editableBlock, 0)
          range.collapse(true)
          selection.removeAllRanges()
          selection.addRange(range)
        }
      } else {
        // 在末尾插入图片
        const tempDiv = document.createElement('div')
        tempDiv.innerHTML = imageHtml
        visualEditor.value.appendChild(tempDiv.firstChild!)
        
        // 在末尾添加可编辑的文本块
        const editableBlock = document.createElement('div')
        editableBlock.className = 'text-content-block'
        editableBlock.contentEditable = 'true'
        editableBlock.style.cssText = 'margin: 0 0 12px 0; font-size: 14px; color: #666; line-height: 1.8; min-height: 20px;'
        editableBlock.innerHTML = '<br>' // 空行占位
        visualEditor.value.appendChild(editableBlock)
        
        // 将光标移到新文本块
        const range = document.createRange()
        range.setStart(editableBlock, 0)
        range.collapse(true)
        const sel = window.getSelection()
        sel?.removeAllRanges()
        sel?.addRange(range)
      }
      
      // 为新插入的图片添加交互功能
      setTimeout(() => {
        const imgElement = visualEditor.value?.querySelector(`img[data-img-id="${imageId}"]`) as HTMLImageElement
        if (imgElement) {
          makeImageInteractive(imgElement, imageId)
        }
      }, 0)
      
      // 触发内容更新（同步到 formData 和预览区）
      handleVisualEditorInput()
    }
    
    message.success(`图片已插入 (小尺寸: ${displayWidth}px, 点击可放大查看原图)`)
    
  } catch (error) {
    console.error('图片处理失败:', error)
    message.error('图片处理失败，请重试')
  } finally {
    uploadingImage.value = false
  }
  
  return false
}

/**
 * 使图片可交互（新版交互方案）
 * 核心功能：
 * 1. 选中时显示快捷尺寸按钮（小/中/大）
 * 2. 支持拖拽图片边缘自由缩放
 * 3. 实时显示当前尺寸数值
 * 4. 平滑动画过渡效果
 * 
 * @param imgElement - 图片DOM元素
 * @param imageId - 图片唯一标识ID
 */
const makeImageInteractive = (imgElement: HTMLImageElement, imageId: string) => {
  // === 状态管理 ===
  let isResizing = false // 是否正在拖拽缩放
  let isSelected = false // 是否选中状态
  let startX = 0 // 拖拽起始X坐标
  let startWidth = 0 // 拖拽起始宽度
  
  // === 基础样式配置 ===
  imgElement.style.transition = 'all 0.3s ease' // 平滑过渡动画
  imgElement.style.cursor = 'pointer'
  
  // === 创建容器包裹结构 ===
  // 使用相对定位容器包裹图片,便于添加控制层（块级布局，避免与文字内联）
  const wrapper = document.createElement('div')
  wrapper.className = 'image-wrapper-interactive'
  wrapper.style.cssText = `
    position: relative;
    display: block;
    max-width: 100%;
    margin: 12px 0;
    clear: both;
  `
  imgElement.parentNode?.insertBefore(wrapper, imgElement)
  wrapper.appendChild(imgElement)
  
  // === 创建选中状态边框 + 尺寸提示层 ===
  const selectionOverlay = document.createElement('div')
  selectionOverlay.className = 'image-selection-overlay'
  selectionOverlay.style.cssText = `
    position: absolute;
    top: -4px;
    left: -4px;
    right: -4px;
    bottom: -4px;
    border: 3px solid #1890ff;
    border-radius: 6px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.3s ease;
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
  `
  wrapper.appendChild(selectionOverlay)
  
  // === 创建实时尺寸显示标签 ===
  const sizeIndicator = document.createElement('div')
  sizeIndicator.className = 'image-size-indicator'
  sizeIndicator.style.cssText = `
    position: absolute;
    top: -32px;
    left: 50%;
    transform: translateX(-50%);
    padding: 4px 12px;
    background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);
    color: white;
    font-size: 12px;
    font-weight: 500;
    border-radius: 12px;
    white-space: nowrap;
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
    box-shadow: 0 2px 8px rgba(24, 144, 255, 0.4);
    z-index: 20;
  `
  wrapper.appendChild(sizeIndicator)
  
  // === 创建快捷尺寸按钮组 ===
  const quickSizeButtons = document.createElement('div')
  quickSizeButtons.className = 'quick-size-buttons'
  quickSizeButtons.style.cssText = `
    position: absolute;
    bottom: -48px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 8px;
    padding: 6px;
    background: rgba(255, 255, 255, 0.95);
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
    opacity: 0;
    transition: opacity 0.3s ease;
    z-index: 20;
  `
  
  // 创建三个快捷尺寸按钮（小/中/大）
  const sizePresets = [
    { label: '📱 小', value: IMAGE_SIZE_PRESETS.small, tooltip: '300px' },
    { label: '💻 中', value: IMAGE_SIZE_PRESETS.medium, tooltip: '500px' },
    { label: '🖥️ 大', value: IMAGE_SIZE_PRESETS.large, tooltip: '800px' }
  ]
  
  sizePresets.forEach(preset => {
    const btn = document.createElement('button')
    btn.className = 'quick-size-btn'
    btn.innerHTML = `${preset.label}<br><span style="font-size: 10px; opacity: 0.8;">${preset.tooltip}</span>`
    btn.style.cssText = `
      padding: 8px 14px;
      border: 2px solid #d9d9d9;
      border-radius: 6px;
      background: white;
      color: #262626;
      font-size: 12px;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.3s ease;
      line-height: 1.4;
      text-align: center;
    `
    
    // 按钮悬停效果
    btn.addEventListener('mouseenter', () => {
      btn.style.borderColor = '#1890ff'
      btn.style.background = '#e6f7ff'
      btn.style.transform = 'translateY(-2px)'
      btn.style.boxShadow = '0 4px 12px rgba(24, 144, 255, 0.3)'
    })
    
    btn.addEventListener('mouseleave', () => {
      btn.style.borderColor = '#d9d9d9'
      btn.style.background = 'white'
      btn.style.transform = 'translateY(0)'
      btn.style.boxShadow = 'none'
    })
    
    // 点击快捷按钮切换尺寸
    btn.addEventListener('click', (e) => {
      e.stopPropagation()
      const image = insertedImages.value.find(img => img.id === imageId)
      if (image) {
        // 计算新尺寸（保持比例）
        const ratio = image.originalHeight / image.originalWidth
        image.width = preset.value
        image.height = Math.round(preset.value * ratio)
        
        // 应用到DOM元素（带动画）
        imgElement.style.width = `${preset.value}px`
        imgElement.style.height = 'auto'
        
        // 更新尺寸提示
        updateSizeIndicator(preset.value)
        
        // 同步所有视图
        syncAllViews()
        
        message.success(`✅ 已调整为${preset.label.substring(2)}尺寸 (${preset.tooltip})`)
      }
    })
    
    quickSizeButtons.appendChild(btn)
  })
  
  wrapper.appendChild(quickSizeButtons)
  
  // === 拖拽缩放核心逻辑（提前声明，供后续使用）===
  const startResizing = (e: MouseEvent) => {
    isResizing = true
    startX = e.clientX
    startWidth = imgElement.offsetWidth
    
    // 禁用过渡动画（拖拽时需要即时响应）
    imgElement.style.transition = 'none'
    
    const onMouseMove = (e: MouseEvent) => {
      if (!isResizing) return
      
      // 计算新宽度（限制在100-1200px之间）
      const deltaX = e.clientX - startX
      const newWidth = Math.max(100, Math.min(startWidth + deltaX, 1200))
      
      // 应用新尺寸（保持宽高比）
      imgElement.style.width = `${newWidth}px`
      imgElement.style.height = 'auto'
      
      // 实时更新尺寸提示
      updateSizeIndicator(newWidth)
      
      // 更新统一数据源
      const image = insertedImages.value.find(img => img.id === imageId)
      if (image) {
        image.width = newWidth
        const ratio = image.originalHeight / image.originalWidth
        image.height = Math.round(newWidth * ratio)
      }
    }
    
    const onMouseUp = () => {
      if (!isResizing) return
      isResizing = false
      
      // 恢复过渡动画
      imgElement.style.transition = 'all 0.3s ease'
      
      // 移除事件监听
      document.removeEventListener('mousemove', onMouseMove)
      document.removeEventListener('mouseup', onMouseUp)
      
      // 同步所有视图
      syncAllViews()
      
      message.success(`✅ 图片已调整为 ${imgElement.offsetWidth}px 宽度`)
    }
    
    document.addEventListener('mousemove', onMouseMove)
    document.addEventListener('mouseup', onMouseUp)
  }
  
  // === 创建边缘拖拽区域（8个方向）===
  const resizeHandles = ['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw']
  const handleElements: { [key: string]: HTMLElement } = {}
  
  resizeHandles.forEach(direction => {
    const handle = document.createElement('div')
    handle.className = `resize-handle-${direction}`
    
    // 根据方向设置位置和光标样式
    const positions: { [key: string]: string } = {
      n: 'top: -4px; left: 50%; transform: translateX(-50%); width: 80%; height: 8px; cursor: ns-resize;',
      ne: 'top: -4px; right: -4px; width: 12px; height: 12px; cursor: nesw-resize;',
      e: 'right: -4px; top: 50%; transform: translateY(-50%); width: 8px; height: 80%; cursor: ew-resize;',
      se: 'bottom: -4px; right: -4px; width: 12px; height: 12px; cursor: nwse-resize;',
      s: 'bottom: -4px; left: 50%; transform: translateX(-50%); width: 80%; height: 8px; cursor: ns-resize;',
      sw: 'bottom: -4px; left: -4px; width: 12px; height: 12px; cursor: nesw-resize;',
      w: 'left: -4px; top: 50%; transform: translateY(-50%); width: 8px; height: 80%; cursor: ew-resize;',
      nw: 'top: -4px; left: -4px; width: 12px; height: 12px; cursor: nwse-resize;'
    }
    
    handle.style.cssText = `
      position: absolute;
      ${positions[direction]}
      background: #1890ff;
      border-radius: 2px;
      opacity: 0;
      transition: opacity 0.3s ease;
      z-index: 15;
    `
    
    // 绑定拖拽缩放事件（仅使用右侧和右下角方向保持宽高比）
    if (['e', 'se'].includes(direction)) {
      handle.addEventListener('mousedown', (e) => {
        e.preventDefault()
        e.stopPropagation()
        startResizing(e)
      })
    }
    
    wrapper.appendChild(handle)
    handleElements[direction] = handle
  })
  
  // === 更新尺寸提示显示 ===
  const updateSizeIndicator = (width: number) => {
    const image = insertedImages.value.find(img => img.id === imageId)
    if (image) {
      sizeIndicator.textContent = `当前宽度: ${width}px (${Math.round(width / image.originalWidth * 100)}%)`
    }
  }
  
  // === 图片选中/取消选中逻辑 ===
  const selectImage = () => {
    isSelected = true
    selectionOverlay.style.opacity = '1'
    quickSizeButtons.style.opacity = '1'
    sizeIndicator.style.opacity = '1'
    
    // 显示边缘拖拽控制点
    Object.values(handleElements).forEach(handle => {
      handle.style.opacity = '0.8'
    })
    
    updateSizeIndicator(imgElement.offsetWidth)
  }
  
  const deselectImage = () => {
    isSelected = false
    selectionOverlay.style.opacity = '0'
    quickSizeButtons.style.opacity = '0'
    sizeIndicator.style.opacity = '0'
    
    // 隐藏边缘拖拽控制点
    Object.values(handleElements).forEach(handle => {
      handle.style.opacity = '0'
    })
  }
  
  // === 事件绑定 ===
  // 单击选中图片（显示控制面板）
  imgElement.addEventListener('click', (e) => {
    e.stopPropagation()
    if (!isSelected) {
      selectImage()
    } else {
      // 已选中状态下单击则预览原图
      const image = insertedImages.value.find(img => img.id === imageId)
      if (image) {
        previewImageUrl.value = image.url
        previewImageName.value = image.name
        imagePreviewVisible.value = true
      }
    }
  })
  
  // 鼠标悬停高亮提示
  wrapper.addEventListener('mouseenter', () => {
    if (!isSelected) {
      imgElement.style.boxShadow = '0 4px 16px rgba(24, 144, 255, 0.2)'
      imgElement.style.transform = 'scale(1.01)'
    }
  })
  
  wrapper.addEventListener('mouseleave', () => {
    if (!isSelected && !isResizing) {
      imgElement.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1)'
      imgElement.style.transform = 'scale(1)'
    }
  })
  
  // 点击编辑器其他区域时取消选中
  document.addEventListener('click', (e) => {
    if (!wrapper.contains(e.target as Node)) {
      deselectImage()
    }
  })
}

// 显示图片右键菜单
const showImageContextMenu = (event: MouseEvent, imageId: string) => {
  // 这里可以实现自定义右键菜单
  // 暂时使用浏览器默认行为
}

// 可视化编辑器内容变化处理（防抖优化）
let editorInputTimer: any = null
const handleVisualEditorInput = () => {
  if (isUpdatingVisualEditor.value) return
  
  // 防抖处理，避免频繁更新
  clearTimeout(editorInputTimer)
  editorInputTimer = setTimeout(() => {
    const editor = visualEditor.value
    if (!editor) return
    
    // 直接保存编辑区的完整 HTML 内容（包含所有列表、表格、图片、标题等）
    // 注意：不再移除任何元素，保持原始顺序
    formData.value.content = editor.innerHTML
    
    // 同步到预览区
    syncAllViews()
  }, 300) // 300ms 防抖
}

// 编辑器点击事件处理（修复光标定位问题）
const handleEditorClick = (event: MouseEvent) => {
  const editor = visualEditor.value
  if (!editor) return
  
  const selection = window.getSelection()
  if (!selection) return
  
  // 检查点击目标是否为图片容器或其子元素
  const target = event.target as HTMLElement
  const isImageWrapper = target.closest('.image-wrapper-interactive')
  
  if (isImageWrapper) {
    // 点击图片区域，不处理（由图片交互逻辑处理）
    return
  }
  
  // 确保点击空白区域时设置正确的光标位置
  // 使用原生 Range API 精确定位
  try {
    const range = document.caretRangeFromPoint(event.clientX, event.clientY)
    if (range && editor.contains(range.startContainer)) {
      selection.removeAllRanges()
      selection.addRange(range)
    }
  } catch (e) {
    // 降级方案：将光标设置到编辑器末尾
    const range = document.createRange()
    range.selectNodeContents(editor)
    range.collapse(false)
    selection.removeAllRanges()
    selection.addRange(range)
  }
}

// 基于统一数据源渲染图片 HTML（自适应编辑器宽度，不溢出，使用块级容器避免文字竖排）
const renderImageFromSource = (image: InsertedImage, editable: boolean = false): string => {
  // 使用 div 包裹，确保图片独占一行，避免文字竖排问题
  const wrapperStyle = `display: block; clear: both; margin: 12px 0;`
  
  // 图片样式
  let imgStyle = `width: ${image.width}px; height: auto; max-width: 100%; display: block;`
  
  // 对齐方式
  if (image.align === 'center') {
    imgStyle += ' margin: 0 auto;'
  } else if (image.align === 'right') {
    imgStyle += ' margin: 0 0 0 auto;'
  } else {
    imgStyle += ' margin: 0;'
  }
  
  // 美化样式
  imgStyle += ' border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); animation: fadeIn 0.5s ease-in; object-fit: contain;'
  
  // 返回带容器的HTML（容器设置 user-select: none 避免影响文字选择）
  return `<div class="image-container-block" style="${wrapperStyle}"><img id="img-${image.id}" data-img-id="${image.id}" src="${image.url}" alt="${image.name}" style="${imgStyle}" /></div>`
}

// 渲染文本内容（不含图片）- 优化列表和表格处理
const renderEditorContent = (): string => {
  let html = formData.value.content
  
  if (!html || html.trim() === '') return ''
  
  // 先转换换行符为 <br>（统一格式）
  html = html.replace(/\n/g, '<br>')
  
  // 表格支持（需要在其他处理之前）
  html = renderMarkdownTable(html)
  
  // 标题（支持行首和 <br> 后的标题）- 适配新的三级标题系统
  html = html.replace(/(^|<br>)### (.+?)(<br>|$)/gm, (match, prefix, content, suffix) => {
    return `${prefix}<div class="heading-style text-content-block" data-heading-level="small" style="font-size: 15px; font-weight: normal; color: #1A365D; margin-top: 12px; margin-bottom: 10px; line-height: 1.5;" contenteditable="true">${content}</div>${suffix}`
  })
  html = html.replace(/(^|<br>)## (.+?)(<br>|$)/gm, (match, prefix, content, suffix) => {
    return `${prefix}<div class="heading-style text-content-block" data-heading-level="medium" style="font-size: 16px; font-weight: bold; color: #444; margin-top: 16px; margin-bottom: 12px; line-height: 1.5;" contenteditable="true">${content}</div>${suffix}`
  })
  html = html.replace(/(^|<br>)# (.+?)(<br>|$)/gm, (match, prefix, content, suffix) => {
    return `${prefix}<div class="heading-style text-content-block" data-heading-level="large" style="font-size: 18px; font-weight: bold; color: #333; border-bottom: 1px solid #e8e8e8; padding-bottom: 8px; margin-top: 20px; margin-bottom: 16px; line-height: 1.5;" contenteditable="true">${content}</div>${suffix}`
  })
  
  // 粗体
  html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
  
  // 斜体（单星号，避免与粗体冲突）
  html = html.replace(/(?<!\*)\*([^*]+?)\*(?!\*)/g, '<em>$1</em>')
  
  // 下划线
  html = html.replace(/__(.+?)__/g, '<u>$1</u>')
  
  // 无序列表（处理连续的列表项）
  const lines = html.split('<br>')
  const processedLines: string[] = []
  let inList = false
  
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i]
    const isListItem = /^-\s+(.+)/.test(line.trim())
    
    if (isListItem) {
      if (!inList) {
        processedLines.push('<ul>')
        inList = true
      }
      const content = line.trim().replace(/^-\s+/, '')
      processedLines.push(`<li>${content}</li>`)
    } else {
      if (inList) {
        processedLines.push('</ul>')
        inList = false
      }
      processedLines.push(line)
    }
  }
  
  if (inList) {
    processedLines.push('</ul>')
  }
  
  html = processedLines.join('<br>')
  
  return html
}

// ========================================
// 核心架构：单一数据源 (Single Source of Truth)
// ========================================

// 统一内容数据源 - 编辑区和预览区的唯一真理源
const unifiedContentSource = ref<string>('')

// 内容同步状态锁（防止循环更新）
const isSyncingContent = ref(false)

// ========================================
// 异常监控与自动修复系统
// ========================================

// 内容一致性验证
const validateContentSync = (editorHtml: string, previewHtml: string): boolean => {
  const editorPure = extractPureContent(editorHtml)
  const previewPure = extractPureContent(previewHtml)
  return editorPure === previewPure
}

// 差异检测与日志记录
const logContentDiff = (editorHtml: string, previewHtml: string) => {
  const editorPure = extractPureContent(editorHtml)
  const previewPure = extractPureContent(previewHtml)
  
  if (editorPure !== previewPure) {
    console.warn('⚠️ 检测到内容不一致')
    console.group('内容差异分析')
    console.log('📊 编辑区长度:', editorPure.length, '字符')
    console.log('📊 预览区长度:', previewPure.length, '字符')
    
    // 逐行对比
    const editorLines = editorPure.split('\n')
    const previewLines = previewPure.split('\n')
    let diffCount = 0
    
    for (let i = 0; i < Math.max(editorLines.length, previewLines.length); i++) {
      if (editorLines[i] !== previewLines[i]) {
        diffCount++
        console.log(`❌ 第${i + 1}行不一致:`, {
          编辑区: editorLines[i]?.substring(0, 100),
          预览区: previewLines[i]?.substring(0, 100)
        })
      }
    }
    
    console.log(`📌 共发现 ${diffCount} 处不一致`)
    console.groupEnd()
    
    return false
  }
  
  console.log('✅ 内容完全一致')
  return true
}

// 自动修复内容同步问题
const autoFixContentSync = () => {
  if (isSyncingContent.value) return
  
  try {
    isSyncingContent.value = true
    
    // 从编辑区读取最新内容作为标准
    if (visualEditor.value) {
      const editorContent = visualEditor.value.innerHTML
      const pureContent = extractPureContent(editorContent)
      
      // 强制更新预览区
      if (previewArea.value) {
        previewArea.value.innerHTML = pureContent
        console.log('🔧 自动修复：已强制同步预览区内容')
      }
      
      // 更新统一数据源
      unifiedContentSource.value = pureContent
    }
  } catch (error) {
    console.error('❌ 自动修复失败:', error)
  } finally {
    isSyncingContent.value = false
  }
}

// ========================================
// 纯净内容提取器：移除所有编辑态控件（加强版）
// 核心原则：仅移除控件，保留100%结构和样式
// ========================================
const extractPureContent = (html: string): string => {
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = html
  
  // ========== 第一步：移除所有编辑态控件类（不影响内容） ==========
  const controlSelectors = [
    '.table-toolbar',
    '.table-edit-btn',
    '.image-resize-controls',
    '.image-align-controls',
    '.size-label',
    '.editable-end-block',
    '.img-resize-handle',
    '.img-delete-btn',
    '.image-selection-overlay',
    '.image-size-indicator',
    '.quick-size-buttons',
    '.resize-handle-n',
    '.resize-handle-ne',
    '.resize-handle-e',
    '.resize-handle-se',
    '.resize-handle-s',
    '.resize-handle-sw',
    '.resize-handle-w',
    '.resize-handle-nw',
    'button',  // 所有按钮
    '.align-btn',
    '.delete-image-btn'
  ]
  
  controlSelectors.forEach(selector => {
    const elements = tempDiv.querySelectorAll(selector)
    elements.forEach(el => el.remove())
  })
  
  // ========== 第二步：移除所有编辑相关属性（保留样式和数据属性） ==========
  const allElements = tempDiv.querySelectorAll('*')
  allElements.forEach(el => {
    // 只移除 contenteditable 属性，其他所有属性（包括 style、class、data-*）全部保留
    el.removeAttribute('contenteditable')
  })
  
  // ========== 第三步：返回100%原始HTML结构 ==========
  return tempDiv.innerHTML
}

// 注意：extractPureContent 函数已在上方定义，此处移除重复定义

// ========================================
// 预览模式样式应用器
// ========================================

const applyPreviewModeStyles = () => {
  if (!previewArea.value) return
  
  // 为所有交互元素添加预览模式标记（仅添加class，不修改样式）
  const tables = previewArea.value.querySelectorAll('.interactive-table-wrapper')
  tables.forEach(wrapper => {
    wrapper.classList.add('preview-mode')
  })
  
  const lists = previewArea.value.querySelectorAll('.interactive-list')
  lists.forEach(list => {
    list.classList.add('preview-mode')
  })
  
  // 图片仅添加点击放大功能（不修改任何样式属性）
  const images = previewArea.value.querySelectorAll('img[data-img-id]')
  images.forEach(img => {
    const imgEl = img as HTMLImageElement
    
    // 只添加点击事件，不修改样式（样式已通过extractPureContent统一）
    imgEl.addEventListener('click', (e) => {
      e.stopPropagation()
      const imageId = imgEl.getAttribute('data-img-id')
      if (imageId) {
        const imageInfo = insertedImages.value.find(img => img.id === imageId)
        if (imageInfo) {
          showImagePreview(imageInfo)
        }
      }
    })
  })
}

// ========================================
// 核心同步函数：单一数据源驱动双向渲染
// ========================================

const syncAllViews = () => {
  if (isUpdatingVisualEditor.value || isSyncingContent.value) return
  
  isUpdatingVisualEditor.value = true
  isSyncingContent.value = true
  
  try {
    // ========================================
    // 编辑区渲染：保持用户输入的原始顺序
    // 注意：编辑区的内容应该完全由用户的输入决定，
    // 不应该在这里重新排列内容的顺序！
    // ========================================
    // 注意：这里不再重建编辑区HTML，因为编辑区的内容
    // 应该由用户的实时输入（handleVisualEditorInput）维护
    
    // ========================================
    // 预览区渲染：强制同步编辑区的完整内容
    // ========================================
    if (previewArea.value && visualEditor.value) {
      // 从编辑区获取完整内容（包含列表、表格、图片、标题等所有元素）
      const editorHtml = visualEditor.value.innerHTML
      
      // 提取纯净内容（移除所有编辑态控件，但保留所有内容元素和顺序）
      const pureContent = extractPureContent(editorHtml)
      
      // 更新统一数据源
      unifiedContentSource.value = pureContent
      
      // 直接赋值到预览区（100%一致，包括顺序）
      previewArea.value.innerHTML = pureContent
      
      console.log('🔄 预览区同步完成，内容长度:', pureContent.length)
      
      // 应用预览模式样式（不修改HTML结构）
      applyPreviewModeStyles()
      
      // 开发环境下进行内容验证
      if (import.meta.env.DEV) {
        const isValid = validateContentSync(editorHtml, previewArea.value.innerHTML)
        
        console.group('📊 内容同步状态')
        console.log('✅ 同步状态:', isValid ? '完全一致' : '存在差异')
        console.log('📏 内容长度:', pureContent.length, '字符')
        console.log('🖼️ 图片数量:', (pureContent.match(/<img/g) || []).length)
        console.log('📋 表格数量:', (pureContent.match(/<table/g) || []).length)
        console.log('📝 列表数量:', (pureContent.match(/<[ou]l/g) || []).length)
        console.groupEnd()
        
        // 如果检测到不一致，触发自动修复
        if (!isValid) {
          logContentDiff(editorHtml, previewArea.value.innerHTML)
          setTimeout(() => autoFixContentSync(), 100)
        }
      }
    }
  } catch (error) {
    console.error('❌ 内容同步失败:', error)
  } finally {
    isUpdatingVisualEditor.value = false
    isSyncingContent.value = false
  }
}

// 标签切换处理（确保同步）
const handleTabChange = (key: string) => {
  syncAllViews()
}

// HTML 转 Markdown（优化版，图片由统一数据源管理）
const convertHtmlToMarkdown = (html: string): string => {
  let markdown = html
  
  // 先转换 <br> 为换行符（统一处理）
  markdown = markdown.replace(/<br\s*\/?>/gi, '\n')
  
  // 标题转换（支持各种格式）- 适配新的三级标题系统
  // 处理 div 标签标题（新的可视化样式）
  markdown = markdown.replace(/<div[^>]*data-heading-level="large"[^>]*>(.*?)<\/div>/gi, '# $1\n')
  markdown = markdown.replace(/<div[^>]*data-heading-level="medium"[^>]*>(.*?)<\/div>/gi, '## $1\n')
  markdown = markdown.replace(/<div[^>]*data-heading-level="small"[^>]*>(.*?)<\/div>/gi, '### $1\n')
  // 处理传统 HTML 标题
  markdown = markdown.replace(/<h1[^>]*>(.*?)<\/h1>/gi, '# $1\n')
  markdown = markdown.replace(/<h2[^>]*>(.*?)<\/h2>/gi, '## $1\n')
  markdown = markdown.replace(/<h3[^>]*>(.*?)<\/h3>/gi, '### $1\n')
  
  // 粗体
  markdown = markdown.replace(/<strong[^>]*>(.*?)<\/strong>/gi, '**$1**')
  markdown = markdown.replace(/<b[^>]*>(.*?)<\/b>/gi, '**$1**')
  
  // 斜体
  markdown = markdown.replace(/<em[^>]*>(.*?)<\/em>/gi, '*$1*')
  markdown = markdown.replace(/<i[^>]*>(.*?)<\/i>/gi, '*$1*')
  
  // 下划线
  markdown = markdown.replace(/<u[^>]*>(.*?)<\/u>/gi, '__$1__')
  
  // 列表转换（无序列表）
  markdown = markdown.replace(/<ul[^>]*>/gi, '')
  markdown = markdown.replace(/<\/ul>/gi, '\n')
  markdown = markdown.replace(/<li[^>]*>(.*?)<\/li>/gi, '- $1\n')
  
  // 表格转换（保留原始表格，已在 renderMarkdownTable 处理）
  // 不做额外处理，保持 Markdown 表格语法
  
  // 清理其他HTML标签（保留文本内容）
  markdown = markdown.replace(/<div[^>]*>/gi, '\n')
  markdown = markdown.replace(/<\/div>/gi, '\n')
  markdown = markdown.replace(/<p[^>]*>/gi, '')
  markdown = markdown.replace(/<\/p>/gi, '\n')
  markdown = markdown.replace(/<span[^>]*>/gi, '')
  markdown = markdown.replace(/<\/span>/gi, '')
  
  // 清理所有剩余的HTML标签
  markdown = markdown.replace(/<[^>]+>/g, '')
  
  // 解码HTML实体
  markdown = markdown.replace(/&nbsp;/g, ' ')
  markdown = markdown.replace(/&lt;/g, '<')
  markdown = markdown.replace(/&gt;/g, '>')
  markdown = markdown.replace(/&amp;/g, '&')
  markdown = markdown.replace(/&quot;/g, '"')
  
  // 清理多余换行（保留双换行作为段落分隔）
  markdown = markdown.replace(/\n{3,}/g, '\n\n')
  
  // 清理首尾空白
  markdown = markdown.trim()
  
  return markdown
}

// 粘贴处理（支持直接粘贴图片和富文本）
const handlePaste = async (event: ClipboardEvent) => {
  const items = event.clipboardData?.items
  if (!items) return
  
  for (let i = 0; i < items.length; i++) {
    const item = items[i]
    
    // 处理粘贴的图片
    if (item.type.startsWith('image/')) {
      event.preventDefault()
      
      const file = item.getAsFile()
      if (file) {
        await handleImageUpload(file)
      }
      return
    }
  }
  
  // 处理富文本粘贴（清理格式，仅保留纯文本）
  if (event.clipboardData) {
    const html = event.clipboardData.getData('text/html')
    const text = event.clipboardData.getData('text/plain')
    
    if (html && html.trim() !== '') {
      // 有HTML内容，阻止默认粘贴，插入纯文本
      event.preventDefault()
      
      // 插入纯文本到光标位置
      const selection = window.getSelection()
      if (selection && selection.rangeCount > 0) {
        const range = selection.getRangeAt(0)
        range.deleteContents()
        const textNode = document.createTextNode(text)
        range.insertNode(textNode)
        range.setStartAfter(textNode)
        range.collapse(true)
        selection.removeAllRanges()
        selection.addRange(range)
      }
      
      // 触发内容更新
      handleVisualEditorInput()
    }
  }
}

// 键盘事件处理
const handleKeydown = (event: KeyboardEvent) => {
  // 检查是否在标题中按回车键
  if (event.key === 'Enter') {
    const selection = window.getSelection()
    if (selection && selection.rangeCount > 0) {
      const currentBlock = getCurrentBlock(selection)
      if (currentBlock && currentBlock.dataset.headingLevel) {
        // 在标题后自动创建普通文本块
        event.preventDefault()
        handleHeadingEnter(currentBlock)
        return
      }
    }
  }
  
  // 支持快捷键
  if (event.ctrlKey || event.metaKey) {
    if (event.key === 'b') {
      event.preventDefault()
      document.execCommand('bold')
    } else if (event.key === 'i') {
      event.preventDefault()
      document.execCommand('italic')
    } else if (event.key === 'u') {
      event.preventDefault()
      document.execCommand('underline')
    }
  }
}

// 处理标题回车键 - 自动创建普通文本块
const handleHeadingEnter = (block: HTMLElement) => {
  // 创建新的普通文本块
  const newBlock = document.createElement('div')
  newBlock.className = 'text-content-block'
  newBlock.contentEditable = 'true'
  newBlock.style.cssText = 'margin: 0 0 12px 0; font-size: 14px; color: #666; line-height: 1.8;'
  newBlock.innerHTML = '<br>' // 空行占位
  
  // 插入到当前标题后
  block.parentElement?.insertBefore(newBlock, block.nextSibling)
  
  // 光标移到新块
  const range = document.createRange()
  range.setStart(newBlock, 0)
  range.collapse(true)
  const selection = window.getSelection()
  selection?.removeAllRanges()
  selection?.addRange(range)
  
  newBlock.focus()
  handleVisualEditorInput()
}

// 聚焦到指定图片
const focusOnImage = (imageId: string) => {
  const imageMarkdown = `#${imageId}`
  const content = formData.value.content
  const index = content.indexOf(imageMarkdown)
  
  if (index !== -1) {
    previewTab.value = 'edit'
    setTimeout(() => {
      const textarea = contentEditor.value?.$el?.querySelector('textarea')
      if (textarea) {
        textarea.focus()
        textarea.setSelectionRange(index, index + imageMarkdown.length)
        textarea.scrollTop = textarea.scrollHeight * (index / content.length)
      }
    }, 100)
  }
}

// 编辑图片样式（一键快捷调整）
const editImageStyle = (imageId: string) => {
  const image = insertedImages.value.find(img => img.id === imageId)
  if (!image) return
  
  currentEditingImageId.value = imageId
  
  // 显示尺寸选择对话框（优化布局）
  const modal = Modal.info({
    title: '📐 调整图片尺寸',
    width: 520,
    okText: '完成',
    content: h('div', { class: 'image-size-selector' }, [
      h('div', { class: 'current-size-info', style: 'margin-bottom: 16px; padding: 12px; background: linear-gradient(135deg, #e6f7ff 0%, #f0f5ff 100%); border-left: 4px solid #1890ff; border-radius: 4px;' }, [
        h('p', { style: 'margin: 0 0 8px 0; font-size: 13px; color: #262626;' }, [
          h('strong', {}, '当前尺寸: '),
          h('span', { style: 'color: #1890ff; font-weight: 500;' }, `${image.width} × ${image.height} px`)
        ]),
        h('p', { style: 'margin: 0; font-size: 13px; color: #595959;' }, [
          h('strong', {}, '原始尺寸: '),
          `${image.originalWidth} × ${image.originalHeight} px`
        ])
      ]),
      h('div', { class: 'size-presets', style: 'margin-bottom: 20px;' }, [
        h('p', { style: 'margin: 0 0 12px 0; font-weight: 600; color: #262626; font-size: 14px;' }, '🎯 快捷尺寸（一键调整）:'),
        h('div', { style: 'display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;' }, [
          h('button', {
            class: 'size-preset-btn',
            style: `padding: 12px 16px; border: 2px solid ${image.width === IMAGE_SIZE_PRESETS.small ? '#1890ff' : '#d9d9d9'}; border-radius: 6px; background: ${image.width === IMAGE_SIZE_PRESETS.small ? '#1890ff' : '#fff'}; color: ${image.width === IMAGE_SIZE_PRESETS.small ? '#fff' : '#262626'}; cursor: pointer; transition: all 0.3s; font-weight: 500; font-size: 13px;`,
            onClick: () => applySizePreset(imageId, 'small')
          }, [
            h('div', { style: 'font-size: 16px; margin-bottom: 4px;' }, '📱'),
            '小',
            h('div', { style: 'font-size: 11px; opacity: 0.8; margin-top: 2px;' }, '300px')
          ]),
          h('button', {
            class: 'size-preset-btn',
            style: `padding: 12px 16px; border: 2px solid ${image.width === IMAGE_SIZE_PRESETS.medium ? '#1890ff' : '#d9d9d9'}; border-radius: 6px; background: ${image.width === IMAGE_SIZE_PRESETS.medium ? '#1890ff' : '#fff'}; color: ${image.width === IMAGE_SIZE_PRESETS.medium ? '#fff' : '#262626'}; cursor: pointer; transition: all 0.3s; font-weight: 500; font-size: 13px;`,
            onClick: () => applySizePreset(imageId, 'medium')
          }, [
            h('div', { style: 'font-size: 16px; margin-bottom: 4px;' }, '💻'),
            '中',
            h('div', { style: 'font-size: 11px; opacity: 0.8; margin-top: 2px;' }, '500px')
          ]),
          h('button', {
            class: 'size-preset-btn',
            style: `padding: 12px 16px; border: 2px solid ${image.width === IMAGE_SIZE_PRESETS.large ? '#1890ff' : '#d9d9d9'}; border-radius: 6px; background: ${image.width === IMAGE_SIZE_PRESETS.large ? '#1890ff' : '#fff'}; color: ${image.width === IMAGE_SIZE_PRESETS.large ? '#fff' : '#262626'}; cursor: pointer; transition: all 0.3s; font-weight: 500; font-size: 13px;`,
            onClick: () => applySizePreset(imageId, 'large')
          }, [
            h('div', { style: 'font-size: 16px; margin-bottom: 4px;' }, '🖥️'),
            '大',
            h('div', { style: 'font-size: 11px; opacity: 0.8; margin-top: 2px;' }, '800px')
          ])
        ])
      ]),
      h('div', { class: 'custom-size-input' }, [
        h('p', { style: 'margin: 0 0 8px 0; font-weight: 600; color: #262626; font-size: 14px;' }, '✏️ 自定义精确宽度:'),
        h('div', { style: 'display: flex; align-items: center; gap: 8px;' }, [
          h('input', {
            type: 'number',
            id: 'custom-width-input',
            placeholder: '输入宽度（px）',
            value: image.width,
            min: 50,
            max: 1200,
            style: 'flex: 1; padding: 10px 12px; border: 2px solid #d9d9d9; border-radius: 4px; font-size: 14px;',
            onInput: (e: any) => {
              const width = parseInt(e.target.value)
              if (!isNaN(width) && width > 0) {
                const ratio = image.originalHeight / image.originalWidth
                const height = Math.round(width * ratio)
                image.width = width
                image.height = height
              }
            }
          }),
          h('span', { style: 'color: #8c8c8c; font-size: 13px; white-space: nowrap;' }, 'px')
        ]),
        h('div', { style: 'margin-top: 8px; padding: 8px 12px; background: #fffbe6; border-radius: 4px;' }, [
          h('p', { style: 'margin: 0; font-size: 12px; color: #d48806;' }, '💡 提示: 图片宽度会自适应编辑器，高度按比例缩放，确保不溢出界面')
        ])
      ])
    ]),
    onOk: () => {
      syncAllViews()
      message.success('图片尺寸已更新')
      modal.destroy()
    }
  })
}

// 应用尺寸预设（一键快捷调整）
const applySizePreset = (imageId: string, preset: 'small' | 'medium' | 'large') => {
  const image = insertedImages.value.find(img => img.id === imageId)
  if (!image) return
  
  const targetWidth = IMAGE_SIZE_PRESETS[preset]
  const ratio = image.originalHeight / image.originalWidth
  const targetHeight = Math.round(targetWidth * ratio)
  
  image.width = targetWidth
  image.height = targetHeight
  
  // 立即同步视图
  syncAllViews()
  
  const sizeLabel = preset === 'small' ? '小 (300px)' : preset === 'medium' ? '中 (500px)' : '大 (800px)'
  message.success(`✅ 已应用${sizeLabel}尺寸`)
}

// 移除图片（同步所有视图，无残留）
const removeImage = (imageId: string) => {
  const index = insertedImages.value.findIndex(img => img.id === imageId)
  if (index === -1) return
  
  const image = insertedImages.value[index]
  
  // 释放临时 URL 内存
  revokeTempUrl(image.url)
  
  // 从编辑区 DOM 中删除图片元素
  if (visualEditor.value) {
    const imgElement = visualEditor.value.querySelector(`img[data-img-id="${imageId}"]`)
    if (imgElement) {
      // 删除图片的容器（image-container-block）
      const container = imgElement.closest('.image-container-block')
      if (container) {
        container.remove()
      } else {
        // 如果没有容器，直接删除图片
        imgElement.remove()
      }
    }
  }
  
  // 从统一数据源移除
  insertedImages.value.splice(index, 1)
  
  // 同步所有视图（确保预览区也删除）
  syncAllViews()
  
  message.success('图片已删除')
}

// 附件上传
const handleFileUpload = (file: File) => {
  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    message.error('文件大小不能超过 10MB')
    return false
  }
  
  const allowedTypes = [
    'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/pdf',
    'application/vnd.ms-excel',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'application/vnd.ms-powerpoint',
    'application/vnd.openxmlformats-officedocument.presentationml.presentation'
  ]
  
  if (!allowedTypes.includes(file.type)) {
    message.error('不支持的文件格式')
    return false
  }
  
  // 这里应该调用实际的上传接口
  // uploadFile(file)
  
  return false
}

// 移除附件
const handleFileRemove = (file: any) => {
  const index = fileList.value.indexOf(file)
  if (index > -1) {
    fileList.value.splice(index, 1)
  }
}

// 确认自定义时间
const confirmCustomTime = () => {
  if (!formData.value.scheduled_time) {
    message.warning('请选择发布时间')
    return
  }
  
  if (formData.value.scheduled_time.isBefore(dayjs())) {
    message.error('发布时间不能早于当前时间')
    return
  }
  
  selectedQuickTime.value = ''
  isCustomTime.value = true
  customTimePickerVisible.value = false
  
  message.success(`已设置定时发布: ${formData.value.scheduled_time.format('YYYY-MM-DD HH:mm')}`)
}

// 预览
const handlePreview = () => {
  if (!formData.value.title || !formData.value.content) {
    message.warning('请先填写标题和内容')
    return
  }
  previewVisible.value = true
}

// 保存草稿
const handleSaveDraft = async () => {
  savingDraft.value = true
  try {
    // 这里应该调用保存草稿的接口
    await new Promise(resolve => setTimeout(resolve, 1000))
    message.success('草稿保存成功')
  } catch (error: any) {
    message.error('草稿保存失败')
  } finally {
    savingDraft.value = false
  }
}

// 提交发布
const handleSubmit = async () => {
  try {
    await formRef.value.validate()
    
    // 权限检查
    if (userRole.value === '部门管理员' && formData.value.scope_type === '全校') {
      message.error('部门管理员不能发布全校公告')
      return
    }
    
    if (userRole.value === '师生用户') {
      message.error('您没有发布公告的权限')
      return
    }
    
    // 范围检查
    if (formData.value.scope_type === '院系' && formData.value.departments.length === 0) {
      message.error('请选择院系')
      return
    }
    if (formData.value.scope_type === '年级' && formData.value.grades.length === 0) {
      message.error('请选择年级')
      return
    }
    if (formData.value.scope_type === '班级' && formData.value.classes.length === 0) {
      message.error('请选择班级')
      return
    }
    
    submitting.value = true
    
    // 构建提交数据
    const submitData = {
      title: formData.value.title,
      content: formData.value.content,
      scope_type: formData.value.scope_type,
      departments: formData.value.departments,
      grades: formData.value.grades,
      classes: formData.value.classes,
      urgency_level: formData.value.urgency_level,
      validity_start: formData.value.validity_period?.[0]?.format('YYYY-MM-DD HH:mm:ss'),
      validity_end: formData.value.validity_period?.[1]?.format('YYYY-MM-DD HH:mm:ss'),
      scheduled_time: formData.value.scheduled_time?.format('YYYY-MM-DD HH:mm:ss'),
      is_pinned: formData.value.is_pinned,
      attachments: fileList.value.map(f => ({
        name: f.name,
        url: f.url || '',
        size: f.size
      }))
    }
    
    // 调用API发布公告
    await announcementAPI.createAnnouncement(submitData as any)
    
    message.success(formData.value.scheduled_time ? '定时发布设置成功' : '发布成功')
    router.push('/announcements/list')
  } catch (error: any) {
    if (error.errorFields) {
      message.error('请填写完整信息')
    } else {
      message.error(error.response?.data?.message || '发布失败')
    }
  } finally {
    submitting.value = false
  }
}

// ========================================
// 调试工具：开发环境下暴露到 window
// ========================================
if (import.meta.env.DEV) {
  (window as any).__announcementEditor__ = {
    checkConsistency: manualCheckConsistency,
    autoFix: autoFixContentSync,
    getUnifiedSource: () => unifiedContentSource.value,
    getEditorContent: () => visualEditor.value?.innerHTML,
    getPreviewContent: () => previewArea.value?.innerHTML,
    extractPure: (html: string) => extractPureContent(html)
  }
  
  console.log('🔧 调试工具已挂载到 window.__announcementEditor__')
}

// 初始化
onMounted(() => {
  // 如果是部门管理员，默认选择本部门
  if (userRole.value === '部门管理员') {
    formData.value.scope_type = '院系'
    const dept = departmentOptions.value.find(d => d.name === userDepartment.value)
    if (dept) {
      formData.value.departments = [dept.id]
    }
  }
  
  // 初始化所有视图
  setTimeout(() => {
    syncAllViews()
    
    // 绑定编辑器点击事件（修复光标定位）
    if (visualEditor.value) {
      visualEditor.value.addEventListener('click', handleEditorClick)
      
      // 初始化已存在的表格和列表
      const tables = visualEditor.value.querySelectorAll('.interactive-table-wrapper')
      tables.forEach(wrapper => makeTableInteractive(wrapper as HTMLElement))
      
      const lists = visualEditor.value.querySelectorAll('.interactive-list')
      lists.forEach(list => makeListInteractive(list as HTMLElement))
    }
    
    // 启动内容一致性监控
    startConsistencyCheck()
    
    console.log('✅ 编辑器初始化完成，已启动内容同步监控')
  }, 100)
  
  // 监听页面卸载，清理临时 URL
  window.addEventListener('beforeunload', cleanupTempUrls)
})

// 组件卸载时清理
onBeforeUnmount(() => {
  stopConsistencyCheck()
  cleanupTempUrls()
})

// 组件卸载时清理
onUnmounted(() => {
  cleanupTempUrls()
  window.removeEventListener('beforeunload', cleanupTempUrls)
  
  // 移除编辑器点击事件监听
  if (visualEditor.value) {
    visualEditor.value.removeEventListener('click', handleEditorClick)
  }
})
</script>

<style scoped>
/* ========================================
   色彩系统变量（轻商务+校园感）
   ======================================== */
:root {
  --primary-color: #6A5ACD; /* 蓝紫色主色调 */
  --primary-light: #9370DB;
  --secondary-color: #E0FFFF; /* 浅青辅助色 */
  --accent-color: #FF6347; /* 红色强调色 */
  --border-light: #E8E8E8;
  --border-focus: #6A5ACD;
  --text-primary: #1A365D;
  --text-secondary: #4A5568;
  --bg-light: #F5F5F5; /* 暖灰底色 */
  --bg-module: #E0FFFF; /* 模块背景浅青色 */
}

/* ========================================
   整体布局优化 - 页面背景色（轻商务+校园感）
   ======================================== */
.announcement-create {
  background: #F5F5F5; /* 暖灰底色 */
  min-height: 100vh;
  padding: 32px;
}

.create-card {
  max-width: 1200px;
  margin: 0 auto;
  background: transparent;
}

/* 表单模块分区 - 自然呼吸感（交替间距）*/
.form-section {
  background: #FFFFFF;
  border-radius: 12px;
  padding: 28px 32px;
  border: 1px solid #E8E8E8;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

/* 第一个模块 */
.form-section:nth-child(1) {
  margin-bottom: 28px; /* 交替间距 - 人工排版感 */
}

/* 第二个模块 */
.form-section:nth-child(2) {
  margin-bottom: 32px; /* 交替间距 */
}

/* 第三个模块 - 公告设置区域 */
.form-section:nth-child(3) {
  margin-bottom: 28px; /* 交替间距 */
}

/* 公告设置区域 - 缩小内部间距50% */
.form-section:nth-child(3) :deep(.ant-form-item) {
  margin-bottom: 12px !important; /* 原24px缩小50% */
}

/* 公告设置标题仅加粗 */
.form-section:nth-child(3) .section-title {
  font-weight: 600;
  font-size: 16px;
}

/* 公告设置所有说明文字统一样式 */
.form-section:nth-child(3) .urgency-hint-right,
.form-section:nth-child(3) .validity-tip,
.form-section:nth-child(3) .time-hint-note,
.form-section:nth-child(3) .pinned-hint {
  color: #999;
  font-size: 12px;
  margin-left: 4px; /* 与对应功能间距缩小为4px */
}

.form-section:hover {
  box-shadow: 0 6px 16px rgba(106, 90, 205, 0.12);
  transform: translateY(-2px);
}

/* 模块标题区 - 自然层次设计（去掉线条，强化字号粗细）*/
.section-header {
  display: flex;
  align-items: center;
  margin-bottom: 24px;
  padding-bottom: 0;
  border-bottom: none;
  position: relative;
}

/* 去掉装饰线 */
.section-header::after {
  display: none;
}

/* 模块序号（增大2px - 强化视觉层级）*/
.section-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;  /* 原36px + 2px */
  height: 38px; /* 原36px + 2px */
  background: linear-gradient(135deg, #46B5D1, #79D4E8);
  color: #fff;
  border-radius: 50%;
  font-weight: bold;
  font-size: 18px;
  margin-right: 14px; /* 略微减小间距，营造手工微调感 */
  box-shadow: 0 3px 8px rgba(70, 181, 209, 0.35);
  transition: all 0.3s ease;
  position: relative;
  left: -2px; /* 手工微调：序号略左移 */
}

/* 序号 hover 时轻微缩放 */
.section-header:hover .section-number {
  transform: scale(1.08); /* 减小缩放幅度，更自然 */
  box-shadow: 0 4px 12px rgba(70, 181, 209, 0.5);
}

/* 模块标题文字 - 提升字号至16px并加粗（去掉下划线）*/
.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #1A365D;
  letter-spacing: 0.3px;
  position: relative;
  display: inline-block;
  padding-bottom: 0;
  padding-left: 2px; /* 手工微调：文字略右移 */
}

/* 去掉标题下划线 */
.section-title::after {
  display: none;
}

/* ========================================
   输入框优化 - 无边框设计
   ======================================== */
.custom-input :deep(.ant-input),
.form-section :deep(.ant-input),
.form-section :deep(.ant-select-selector),
.form-section :deep(.ant-picker),
.form-section :deep(.ant-input-textarea textarea) {
  border: none;
  border-radius: 0;
  padding-bottom: 10px;
  transition: all 0.3s ease;
  background: transparent;
  box-shadow: none;
  color: #262626;
}

.custom-input :deep(.ant-input:hover),
.form-section :deep(.ant-input:hover),
.form-section :deep(.ant-select-selector:hover),
.form-section :deep(.ant-picker:hover),
.form-section :deep(.ant-input-textarea textarea:hover) {
  background: rgba(0, 0, 0, 0.02); /* 悬浮时浅色背景 */
}

.custom-input :deep(.ant-input:focus),
.form-section :deep(.ant-input:focus),
.form-section :deep(.ant-select-focused .ant-select-selector),
.form-section :deep(.ant-picker-focused),
.form-section :deep(.ant-input-textarea-focused textarea) {
  box-shadow: none;
  outline: none;
  background: transparent;
}

/* 字数统计提示 - 移至输入框下方 */
.form-section :deep(.ant-input-textarea-show-count::after) {
  position: relative;
  display: block;
  margin-top: 4px;
  font-size: 12px;
  color: #999; /* 浅灰色小字 */
  text-align: right;
}

/* ========================================
   紧急程度 - 紧凑横向布局（8px间距）
   ======================================== */
/* 紧急程度外层包装 */
.urgency-wrapper {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 单选按钮组 - 紧凑横向排列 */
.urgency-radio-group {
  display: flex;
  gap: 8px !important; /* 紧凑间距8px */
  align-items: center;
}

/* 普通选项的绿色样式 */
.urgency-normal-text {
  color: #52C41A;
}

.urgency-radio-group :deep(.ant-radio-wrapper:has(.urgency-normal-text) .ant-radio-inner) {
  border-color: #52C41A;
}

.urgency-radio-group :deep(.ant-radio-wrapper:has(.urgency-normal-text) .ant-radio-checked .ant-radio-inner) {
  border-color: #52C41A;
  background-color: #52C41A;
}

/* 重要选项的橙色样式 */
.urgency-important-text {
  color: #FA8C16;
}

.urgency-radio-group :deep(.ant-radio-wrapper:has(.urgency-important-text) .ant-radio-inner) {
  border-color: #FA8C16;
}

.urgency-radio-group :deep(.ant-radio-wrapper:has(.urgency-important-text) .ant-radio-checked .ant-radio-inner) {
  border-color: #FA8C16;
  background-color: #FA8C16;
}

/* 紧急选项的红色样式 */
.urgency-urgent-text {
  color: #FF4D4F;
}

.urgency-radio-group :deep(.ant-radio-wrapper:has(.urgency-urgent-text) .ant-radio-inner) {
  border-color: #FF4D4F;
}

.urgency-radio-group :deep(.ant-radio-wrapper:has(.urgency-urgent-text) .ant-radio-checked .ant-radio-inner) {
  border-color: #FF4D4F;
  background-color: #FF4D4F;
}

/* 紧急提示文字 - 浅灰色右对齐 */
.urgency-hint-right {
  margin-left: auto;
  color: #999;
  font-size: 12px;
  white-space: nowrap;
}

/* ========================================
   有效期 - 横向紧挨布局，中间箭头连接
   ======================================== */
.validity-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
}

.validity-picker-start,
.validity-picker-end {
  flex: 1;
  max-width: 280px;
}

.validity-picker-start :deep(.ant-picker),
.validity-picker-end :deep(.ant-picker) {
  border: 1px solid #d9d9d9 !important;
  border-radius: 4px !important;
}

.validity-picker-start :deep(.ant-picker:hover),
.validity-picker-end :deep(.ant-picker:hover) {
  border-color: #d9d9d9 !important;
}

.validity-picker-start :deep(.ant-picker-focused),
.validity-picker-end :deep(.ant-picker-focused) {
  border-color: #d9d9d9 !important;
}

.validity-arrow {
  color: #999;
  font-size: 16px;
  font-weight: 300;
  padding: 0 4px;
}

.validity-tip {
  margin-left: 12px;
  color: #999;
  font-size: 12px;
  white-space: nowrap;
}

/* ========================================
   定时发布区域 - 添加图标，缩小间距
   ======================================== */
.scheduled-publish-container {
  background: #F8F9FA;
  border-radius: 6px;
  padding: 12px 16px; /* 缩小内边距 */
  transition: all 0.3s ease;
}

.scheduled-header {
  display: flex;
  align-items: center;
  gap: 4px; /* 图标与文字间距4px */
}

.setting-icon {
  font-size: 16px;
  color: #46B5D1;
}

.scheduled-title {
  font-size: 14px;
  font-weight: 500;
  color: #333;
  flex: 1;
}

/* ========================================
   置顶区域 - 添加图标，缩小间距
   ======================================== */
.pinned-wrapper {
  display: flex;
  align-items: center;
  gap: 4px; /* 图标与文字间距4px */
  padding: 12px 16px;
  background: #F8F9FA;
  border-radius: 6px;
}

.pinned-title {
  font-size: 14px;
  font-weight: 500;
  color: #333;
  margin-right: 12px;
}

.pinned-hint {
  margin-left: 12px;
  color: #999;
  font-size: 12px;
}

/* ========================================
   工具栏按钮样式优化（蓝紫色系）
   ======================================== */
.toolbar-btn {
  border-radius: 8px;
  transition: all 0.3s ease;
  font-weight: 500;
  border: 1px solid #E0E0E0;
}

.toolbar-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 3px 8px rgba(106, 90, 205, 0.15);
}

.heading-btn {
  min-width: 80px;
  background: linear-gradient(135deg, #F5F0FF 0%, #EDE7F6 100%); /* 浅紫色渐变背景 */
  border-color: #D1C4E9;
  color: #6A5ACD;
  position: relative;
  overflow: hidden;
}

.heading-btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  border-radius: 50%;
  background: rgba(147, 112, 219, 0.2);
  transform: translate(-50%, -50%);
  transition: width 0.6s, height 0.6s;
}

.heading-btn:hover::before {
  width: 300px;
  height: 300px;
}

.heading-btn:hover,
.heading-btn.ant-btn-primary {
  background: linear-gradient(135deg, #6A5ACD 0%, #9370DB 100%); /* 蓝紫色渐变 */
  border-color: #6A5ACD;
  color: #fff;
  box-shadow: 0 4px 12px rgba(106, 90, 205, 0.4);
  transform: translateY(-2px);
}

.toolbar-btn:active {
  transform: scale(0.95) !important;
  transition: transform 0.1s ease;
}

/* ========================================
   操作按钮样式优化（三按钮布局）
   ======================================== */
.submit-btn,
.cancel-btn {
  min-width: 140px;
  height: 48px; /* 加高便于点击 */
  border-radius: 24px; /* 胶囊设计 */
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.5px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

/* 发布按钮 - 蓝紫色渐变填充 + 光泽扫过动画 */
.submit-btn {
  background: linear-gradient(135deg, #6A5ACD, #9370DB); /* 蓝紫色渐变 */
  border: none;
  color: #fff;
  box-shadow: 0 6px 16px rgba(106, 90, 205, 0.4);
}

.submit-btn::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
  transition: left 0.6s ease;
}

.submit-btn:hover {
  background: linear-gradient(135deg, #5848B0, #7B68EE); /* 深紫色渐变 */
  box-shadow: 0 8px 20px rgba(106, 90, 205, 0.5);
  transform: translateY(-3px) scale(1.02);
}

.submit-btn:hover::before {
  left: 100%; /* 光泽扫过效果 */
}

.submit-btn:active {
  transform: translateY(-1px) scale(0.98);
}

/* 保存草稿按钮 - 灰色边框 */
.cancel-btn {
  background: transparent;
  border: 2px solid #BDBDBD;
  color: #757575;
}

.cancel-btn:hover {
  background: rgba(189, 189, 189, 0.1);
  border-color: #9E9E9E;
  color: #616161;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 预览按钮 - 蓝紫色边框样式 */
.preview-btn {
  min-width: 140px;
  height: 48px;
  border-radius: 24px;
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.5px;
  background: transparent;
  border: 2px solid #6A5ACD;
  color: #6A5ACD;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.preview-btn:hover {
  background: rgba(106, 90, 205, 0.05);
  border-color: #9370DB;
  color: #9370DB;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(106, 90, 205, 0.15);
}

/* 操作按钮组容器 */
.action-buttons-group {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-top: 40px;
  padding: 28px 0;
  border-top: 2px solid #E8E8E8;
  background: linear-gradient(to bottom, transparent, #FAFAFA);
}

/* ========================================
   开关控件 - 滑动式渐变开关（蓝紫色）
   ======================================== */
:deep(.ant-switch) {
  background: #BDBDBD; /* 未开启时浅灰 */
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

:deep(.ant-switch-checked) {
 /*background: linear-gradient(135deg, #6A5ACD, #9370DB) !important; */ /* 开启时蓝紫色渐变 */
  box-shadow: 0 2px 8px rgba(106, 90, 205, 0.3);
}

:deep(.ant-switch-handle) {
  transition: all 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55); /* 弹性回弹动画 */
}

:deep(.ant-switch:hover) {
  box-shadow: 0 0 8px rgba(106, 90, 205, 0.2);
}

/* ========================================
   表单验证反馈 - 红色图标+提示文字
   ======================================== */
:deep(.ant-form-item-has-error .ant-input),
:deep(.ant-form-item-has-error .ant-input-textarea textarea),
:deep(.ant-form-item-has-error .ant-select-selector),
:deep(.ant-form-item-has-error .ant-picker) {
  border-color: #FF6347 !important; /* 红色强调色 */
  box-shadow: 0 0 0 2px rgba(255, 99, 71, 0.1);
}

:deep(.ant-form-item-explain-error) {
  color: #FF6347;
  font-size: 13px;
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 4px;
}

:deep(.ant-form-item-explain-error::before) {
  content: '⚠️';
  font-size: 14px;
}

/* ========================================
   通知样式 - 蓝紫色通知条
   ======================================== */
:deep(.ant-message-success) {
  background: linear-gradient(135deg, #6A5ACD, #9370DB);
  color: #fff;
  box-shadow: 0 4px 12px rgba(106, 90, 205, 0.3);
  border-radius: 8px;
  padding: 12px 20px;
}

:deep(.ant-message-success .anticon) {
  color: #fff;
}

/* ========================================
   公告标题输入框 - 只保留最外层边框
   ======================================== */
/* 公告标题输入框包装器 - 只保留最外层框 */
.title-input-wrapper {
  position: relative;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  padding: 8px 12px;
  transition: all 0.3s ease;
  background: #fff;
}

.title-input-wrapper:hover {
  border-color: #40a9ff;
}

.title-input-wrapper:focus-within {
  border-color: #1890ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

/* 内部输入框去掉所有边框和样式 */
.title-input-wrapper :deep(.ant-input) {
  border: none !important;
  padding: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  outline: none !important;
}

.title-input-wrapper :deep(.ant-input:hover),
.title-input-wrapper :deep(.ant-input:focus) {
  border: none !important;
  box-shadow: none !important;
  outline: none !important;
}

/* 字数统计放在输入框外部右侧 */
.title-char-count {
  margin-top: 4px;
  text-align: right;
  font-size: 12px;
  color: #999;
}

/* ========================================
   富文本编辑器美化（蓝紫色系）
   ======================================== */
.editor-container {
  border: 2px solid #E0E0E0; /* 浅灰边框 */
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 16px rgba(106, 90, 205, 0.08);
  transition: all 0.3s ease;
}

.editor-container:hover {
  box-shadow: 0 6px 24px rgba(106, 90, 205, 0.15);
  border-color: #D1C4E9;
}

.editor-toolbar {
  padding: 14px 16px;
  background: linear-gradient(135deg, #F9F8FC 0%, #F5F3F9 100%); /* 浅紫色渐变背景 */
  border-bottom: 2px solid #E0E0E0;
}

.visual-editor-area {
  min-height: 400px;
  background: #fff;
  box-shadow: inset 0 2px 8px rgba(106, 90, 205, 0.03);
  transition: all 0.3s ease;
}

.visual-editor-area:focus {
  background: #FDFCFE;
  box-shadow: inset 0 0 0 3px rgba(106, 90, 205, 0.08);
}

/* ========================================
   预览模式过渡动效
   ======================================== */
.preview-tabs :deep(.ant-tabs-tab) {
  transition: all 0.3s ease;
  border-radius: 8px 8px 0 0;
  margin: 0 4px;
}

.preview-tabs :deep(.ant-tabs-tab:hover) {
  background: rgba(106, 90, 205, 0.08);
}

.preview-tabs :deep(.ant-tabs-tab-active) {
  background: linear-gradient(135deg, #F5F0FF 0%, #EDE7F6 100%); /* 浅紫色渐变 */
  font-weight: 600;
  color: #6A5ACD;
}

.rich-preview-area,
.visual-editor-area {
  animation: fadeInContent 0.4s ease-in-out;
}

@keyframes fadeInContent {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ========================================
   提示文字样式 - 12px #999
   ======================================== */

.tip {
  margin-top: 8px;
  color: #999; /* 辅助说明色 */
  font-size: 12px;
  line-height: 1.6;
}

/* ========================================
   功能按钮 - 圆角标签式设计（蓝紫色强调）
   ======================================== */
.time-option-btn,
.quick-time-btn {
  border-radius: 20px; /* 圆角标签 */
  background: #F5F5F5;
  border: 2px solid #E0E0E0;
  color: #666;
  padding: 8px 20px;
  font-size: 13px;
  transition: all 0.3s ease;
}

.time-option-btn:hover,
.quick-time-btn:hover {
  background: #EBEBEB;
  border-color: #9370DB;
  color: #6A5ACD;
  transform: translateY(-2px);
  box-shadow: 0 3px 8px rgba(106, 90, 205, 0.2);
}

.time-option-btn.active,
.quick-time-btn.active,
.time-option-btn:active,
.quick-time-btn:active {
  background: linear-gradient(135deg, #6A5ACD, #9370DB); /* 蓝紫色渐变填充 */
  border-color: #6A5ACD;
  color: #fff;
  box-shadow: 0 4px 12px rgba(106, 90, 205, 0.35);
}



/* ========================================
   富文本编辑器样式系统（全局规则）
   ======================================== */
/*
 * 核心原则：预览区必须 100% 复用编辑区的样式规则
 * 
 * 1. 标题样式同步：
 *    - 大标题：font-size: 18px, font-weight: bold, color: #333
 *    - 中标题：font-size: 16px, font-weight: bold, color: #444
 *    - 小标题：font-size: 15px, font-weight: normal, color: #1A365D
 *    - 上下间距、行高、边框完全一致
 * 
 * 2. 列表样式同步：
 *    - 缩进距离：padding-left: 24px
 *    - 项目间距：margin: 6px 0
 *    - 项目内边距：padding: 4px 8px
 *    - 行高：line-height: 1.8
 *    - 项目符号：无序(disc)、有序(decimal)
 * 
 * 3. 容器参数一致：
 *    - padding: 20px
 *    - border: 2px solid #e8e8e8
 *    - line-height: 1.8
 *    - font-size: 14px
 * 
 * 4. 禁止使用预览专属样式：
 *    - 禁止在预览区使用与编辑区不同的颜色、字号、间距
 *    - 禁止在预览区自定义与编辑区冲突的 CSS 规则
 */

/* ========================================
   实时预览区样式 - 与编辑区完全一致（强制统一）
   所有容器参数必须100%相同
   ======================================== */
.rich-preview-area {
  padding: 20px;           /* 与编辑区完全一致 */
  min-height: 500px;       /* 与编辑区完全一致 */
  max-height: 800px;       /* 与编辑区完全一致 */
  overflow-y: auto;        /* 与编辑区完全一致 */
  background: #fff;        /* 与编辑区完全一致 */
  border: 2px solid #e8e8e8;  /* 修正：与编辑区保持一致的2px边框 */
  border-radius: 4px;      /* 新增：与编辑区保持一致 */
  line-height: 1.8;        /* 与编辑区完全一致 */
  font-size: 14px;         /* 与编辑区完全一致 */
  color: #262626;          /* 与编辑区完全一致 */
  word-wrap: break-word;   /* 与编辑区完全一致 */
  word-break: break-word;  /* 与编辑区完全一致 */
  white-space: normal;     /* 与编辑区完全一致 */
  cursor: default;         /* 预览模式不可编辑 */
}

/* 预览区文本块样式 */
.rich-preview-area :deep(.text-content-block) {
  display: block;
  width: 100%;
  margin: 0 0 12px 0;
  white-space: normal;
  word-wrap: break-word;
  word-break: break-word;
  line-height: 1.8;
}

/* ========================================
   预览区标题样式 - 与编辑区 100% 一致（强制同步）
   所有属性值必须与编辑区完全相同
   ======================================== */
.rich-preview-area :deep(.heading-style) {
  display: block;
  width: 100%;
  white-space: normal;
  word-wrap: break-word;
  word-break: break-word;
}

/* 大标题 - 与编辑区完全一致 */
.rich-preview-area :deep([data-heading-level="large"]) {
  font-size: 18px !important;          /* 与编辑区完全一致 */
  font-weight: bold !important;        /* 与编辑区完全一致 */
  color: #333 !important;              /* 与编辑区完全一致 */
  border-bottom: 1px solid #e8e8e8 !important;  /* 与编辑区完全一致 */
  padding-bottom: 8px !important;      /* 与编辑区完全一致 */
  margin-top: 20px !important;         /* 与编辑区完全一致 */
  margin-bottom: 16px !important;      /* 与编辑区完全一致 */
  line-height: 1.5 !important;         /* 与编辑区完全一致 */
  display: block;
  width: 100%;
}

/* 中标题 - 与编辑区完全一致 */
.rich-preview-area :deep([data-heading-level="medium"]) {
  font-size: 16px !important;          /* 与编辑区完全一致 */
  font-weight: bold !important;        /* 与编辑区完全一致 */
  color: #444 !important;              /* 与编辑区完全一致 */
  margin-top: 16px !important;         /* 与编辑区完全一致 */
  margin-bottom: 12px !important;      /* 与编辑区完全一致 */
  line-height: 1.5 !important;         /* 与编辑区完全一致 */
  display: block;
  width: 100%;
}

/* 小标题 - 与编辑区完全一致 */
.rich-preview-area :deep([data-heading-level="small"]) {
  font-size: 15px !important;          /* 与编辑区完全一致 */
  font-weight: normal !important;      /* 与编辑区完全一致 */
  color: #1A365D !important;           /* 与编辑区完全一致 */
  margin-top: 12px !important;         /* 与编辑区完全一致 */
  margin-bottom: 10px !important;      /* 与编辑区完全一致 */
  line-height: 1.5 !important;         /* 与编辑区完全一致 */
  display: block;
  width: 100%;
}

/* 预览区文本格式样式 */
.rich-preview-area :deep(strong) {
  font-weight: bold;
  color: #000;
}

/* 文本格式：与编辑区一致 */
.rich-preview-area :deep(strong) {
  font-weight: bold;
}

.rich-preview-area :deep(em) {
  font-style: italic;
}

.rich-preview-area :deep(u) {
  text-decoration: underline;
}

/* 图片样式 - 与编辑区完全一致 */
.rich-preview-area :deep(img) {
  max-width: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  display: block;
}

/* 图片容器 - 与编辑区完全一致 */
.rich-preview-area :deep(.image-container-block) {
  display: block;
  clear: both;
  margin: 12px 0;
}

/* ========================================
   预览区列表样式 - 与编辑区 100% 一致（强制同步）
   项目符号、缩进、行高必须完全相同
   ======================================== */
.rich-preview-area :deep(.interactive-list) {
  margin: 12px 0 !important;           /* 与编辑区完全一致 */
  padding-left: 24px !important;       /* 与编辑区完全一致 */
  list-style-position: outside !important;  /* 与编辑区完全一致 */
}

.rich-preview-area :deep(.interactive-list li) {
  margin: 6px 0 !important;            /* 与编辑区完全一致 */
  padding: 4px 8px !important;         /* 与编辑区完全一致 */
  min-height: 24px !important;         /* 与编辑区完全一致 */
  line-height: 1.8 !important;         /* 与编辑区完全一致（重要）*/
}

/* 无序列表项目符号样式 - 与编辑区完全一致 */
.rich-preview-area :deep(ul.interactive-list) {
  list-style-type: disc !important;    /* 圆点符号 */
}

/* 有序列表编号样式 - 与编辑区完全一致 */
.rich-preview-area :deep(ol.interactive-list) {
  list-style-type: decimal !important; /* 数字编号 */
}

/* ========================================
   样式层完全复用：预览区与编辑区共享样式
   ======================================== */

/* 预览区禁用所有编辑功能 */
.rich-preview-area {
  user-select: text;
  cursor: default;
}

.rich-preview-area * {
  cursor: default !important;
}

.rich-preview-area img {
  cursor: zoom-in !important; /* 仅图片可放大 */
}

/* ========================================
   预览区彻底隐藏所有编辑态控件（加强版 + CSS兜底）
   策略：CSS强制隐藏 + JS DOM移除双重保险
   不占用任何布局空间，不影响内容排版
   ======================================== */
.rich-preview-area :deep(.table-toolbar),
.rich-preview-area :deep(.table-edit-btn),
.rich-preview-area :deep(.image-resize-controls),
.rich-preview-area :deep(.image-align-controls),
.rich-preview-area :deep(.size-label),
.rich-preview-area :deep(.editable-end-block),
.rich-preview-area :deep(.img-resize-handle),
.rich-preview-area :deep(.img-delete-btn),
.rich-preview-area :deep(.image-selection-overlay),
.rich-preview-area :deep(.image-size-indicator),
.rich-preview-area :deep(.quick-size-buttons),
.rich-preview-area :deep(.resize-handle-n),
.rich-preview-area :deep(.resize-handle-ne),
.rich-preview-area :deep(.resize-handle-e),
.rich-preview-area :deep(.resize-handle-se),
.rich-preview-area :deep(.resize-handle-s),
.rich-preview-area :deep(.resize-handle-sw),
.rich-preview-area :deep(.resize-handle-w),
.rich-preview-area :deep(.resize-handle-nw),
.rich-preview-area :deep(button),
.rich-preview-area :deep(.align-btn),
.rich-preview-area :deep(.delete-image-btn),
.rich-preview-area :deep(.image-wrapper-interactive .quick-size-buttons),
.rich-preview-area :deep(.image-wrapper-interactive .image-selection-overlay),
.rich-preview-area :deep(.image-wrapper-interactive .image-size-indicator),
.rich-preview-area :deep([class^="resize-handle-"]) {
  display: none !important;
  visibility: hidden !important;
  opacity: 0 !important;
  pointer-events: none !important;
  position: absolute !important;
  left: -9999px !important; /* 确保完全移出可视区域 */
}

/* ========================================
   预览区样式：100%复用编辑区规则
   ======================================== */

/* 表格样式 - 与编辑区完全一致 */
.rich-preview-area :deep(.interactive-table-wrapper) {
  margin: 16px 0;
  overflow-x: auto;
}

.rich-preview-area :deep(.interactive-table) {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  line-height: 1.6;
}

.rich-preview-area :deep(.interactive-table th),
.rich-preview-area :deep(.interactive-table td) {
  border: 1px solid #d9d9d9;
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
  background: #fff;
}

.rich-preview-area :deep(.interactive-table th) {
  background: #fafafa;
  font-weight: 600;
  color: #262626;
}

.rich-preview-area :deep(.interactive-table td) {
  color: #595959;
}

/* ========================================
   预览区嵌套列表样式 - 与编辑区完全一致
   ======================================== */
.rich-preview-area :deep(.interactive-list .interactive-list) {
  margin-left: 0 !important;           /* 嵌套列表不额外偏移 */
  margin-top: 6px !important;
  margin-bottom: 6px !important;
  padding-left: 24px !important;       /* 保持与父列表相同的缩进 */
}

/* 预览区图片样式 - 校园公告风格 */
.rich-preview-area :deep(.image-container-block) {
  margin: 16px 0;
  clear: both;
  display: block;
}

.rich-preview-area :deep(.image-container-block img) {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: transform 0.2s ease;
}

.rich-preview-area :deep(.image-container-block img:hover) {
  transform: scale(1.01);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

/* ========================================
   注意：此处样式已在上方统一定义，此处删除重复定义
   避免样式冲突导致预览区与编辑区不一致
   ======================================== */

/* 预览区文本内容样式 */
.rich-preview-area :deep(.text-content-block) {
  font-size: 15px;
  line-height: 1.8;
  color: #262626;
  margin-bottom: 12px;
  text-align: justify;
  word-break: break-word;
}

/* 预览区强调样式 */
.rich-preview-area :deep(strong) {
  font-weight: 600;
  color: #000;
}

.rich-preview-area :deep(em) {
  font-style: italic;
  color: #595959;
}

.rich-preview-area :deep(u) {
  text-decoration: underline;
  text-decoration-color: #1890ff;
  text-underline-offset: 2px;
}

/* ========================================
   移动端适配（编辑区与预览区同步调整）
   ======================================== */

.rich-preview-area :deep(img:hover) {
  transform: scale(1.02);
  box-shadow: 0 4px 16px rgba(24, 144, 255, 0.2);
  cursor: zoom-in;
}

/* 图片加载动画 */
.rich-preview-area :deep(img) {
  animation: fadeIn 0.5s ease-in;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.preview-tabs {
  margin-top: 0;
  border-top: 1px solid #d9d9d9;
}

.preview-tabs :deep(.ant-tabs-nav) {
  margin: 0;
  padding: 0 12px;
  background: #fafafa;
}

.preview-tabs :deep(.ant-tabs-nav::before) {
  border-bottom: none !important;
}

.preview-tabs :deep(.ant-tabs-ink-bar) {
  display: none !important;
}

/* 已插入图片管理区 */
.inserted-images-manager {
  margin-top: 12px;
  padding: 12px;
  background: #fafafa;
  border-radius: 4px;
  border-top: 1px solid #d9d9d9;
}

.image-item {
  position: relative;
  width: 120px;
  height: 120px;
  border: 2px solid #d9d9d9;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.3s;
}

.image-item:hover {
  border-color: #1890ff;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2);
}

.image-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-item-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s;
}

.image-item:hover .image-item-mask {
  opacity: 1;
}

/* 可视化编辑器样式（核心功能 - 原图展示）*/
.visual-editor-area {
  min-height: 500px;
  max-height: 800px;
  overflow-y: auto;
  padding: 20px;
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 4px;
  line-height: 1.8;
  font-size: 14px;
  color: #262626;
  outline: none;
  cursor: text;
  word-wrap: break-word; /* 文字自动换行 */
  word-break: break-word; /* 长单词断行 */
  white-space: normal; /* 确保正常换行，避免竖排 */
}

.visual-editor-area:focus {
  border-color: #f0f0f0;
  box-shadow: none;
}

.visual-editor-area:empty:before {
  content: '';
  color: #999;
  font-style: italic;
  pointer-events: none;
}

/* 文本内容块 - 确保横向流式布局 */
.visual-editor-area :deep(.text-content-block) {
  display: block;
  width: 100%;
  margin: 0 0 12px 0;
  white-space: normal; /* 正常换行 */
  word-wrap: break-word;
  word-break: break-word;
  line-height: 1.8;
}

/* 标题样式 - 适配校园场景 */
.visual-editor-area :deep(.heading-style) {
  display: block;
  width: 100%;
  outline: none;
  cursor: text;
  white-space: normal;
  word-wrap: break-word;
  word-break: break-word;
}

/* 大标题样式 */
.visual-editor-area :deep([data-heading-level="large"]) {
  font-size: 18px;
  font-weight: bold;
  color: #333;
  border-bottom: 1px solid #e8e8e8;
  padding-bottom: 8px;
  margin-top: 20px;
  margin-bottom: 16px;
  line-height: 1.5;
}

/* 中标题样式 */
.visual-editor-area :deep([data-heading-level="medium"]) {
  font-size: 16px;
  font-weight: bold;
  color: #444;
  margin-top: 16px;
  margin-bottom: 12px;
  line-height: 1.5;
}

/* 小标题样式 */
.visual-editor-area :deep([data-heading-level="small"]) {
  font-size: 15px;
  font-weight: normal;
  color: #1A365D;
  margin-top: 12px;
  margin-bottom: 10px;
  line-height: 1.5;
}

/* 图片容器块 - 独占一行，避免文字竖排 */
.visual-editor-area :deep(.image-container-block) {
  display: block;
  clear: both;
  margin: 12px 0;
  width: 100%;
  user-select: none; /* 避免影响文字选择 */
}

/* 末尾可编辑区域 - 确保图片后可以输入 */
.visual-editor-area :deep(.editable-end-block) {
  display: block;
  min-height: 24px;
  width: 100%;
  margin-top: 12px;
}

/* 可视化编辑器中的图片 - 自适应宽度，保持比例不溢出 */
.visual-editor-area img {
  max-width: 100%; /* 自适应编辑器宽度 */
  width: auto; /* 保持原始宽度设置 */
  height: auto; /* 高度按比例自动缩放 */
  object-fit: contain; /* 保持比例且完整显示 */
  border-radius: 6px;
  cursor: zoom-in;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  user-select: none;
  display: block;
}

.visual-editor-area img:hover {
  box-shadow: 0 4px 20px rgba(24, 144, 255, 0.25);
}

.visual-editor-area img:active {
  transform: scale(0.99);
}

/* === 新版图片交互样式 === */

/* 图片容器包裹层（块级布局，避免与文字内联导致光标异常）*/
.image-wrapper-interactive {
  position: relative;
  display: block;
  max-width: 100%;
  margin: 12px 0;
  clear: both;
}

/* 选中状态边框高亮 */
.image-selection-overlay {
  position: absolute;
  top: -4px;
  left: -4px;
  right: -4px;
  bottom: -4px;
  border: 3px solid #1890ff;
  border-radius: 6px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

/* 实时尺寸显示标签 */
.image-size-indicator {
  position: absolute;
  top: -32px;
  left: 50%;
  transform: translateX(-50%);
  padding: 4px 12px;
  background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);
  color: white;
  font-size: 12px;
  font-weight: 500;
  border-radius: 12px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(24, 144, 255, 0.4);
  z-index: 20;
  animation: slideDown 0.3s ease-out;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

/* 快捷尺寸按钮组容器 */
.quick-size-buttons {
  position: absolute;
  bottom: -48px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  padding: 6px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  opacity: 0;
  transition: opacity 0.3s ease;
  z-index: 20;
  animation: slideUp 0.3s ease-out;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

/* 快捷尺寸按钮 */
.quick-size-btn {
  padding: 8px 14px;
  border: 2px solid #d9d9d9;
  border-radius: 6px;
  background: white;
  color: #262626;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  line-height: 1.4;
  text-align: center;
}

.quick-size-btn:hover {
  border-color: #1890ff;
  background: #e6f7ff;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(24, 144, 255, 0.3);
}

.quick-size-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(24, 144, 255, 0.2);
}

/* 边缘拖拽控制点（8个方向）*/
[class^="resize-handle-"] {
  position: absolute;
  background: #1890ff;
  border-radius: 2px;
  opacity: 0;
  transition: opacity 0.3s ease;
  z-index: 15;
}

[class^="resize-handle-"]:hover {
  background: #40a9ff;
  opacity: 1 !important;
  box-shadow: 0 2px 8px rgba(24, 144, 255, 0.5);
}

/* 可视化编辑器中的文本样式 */
.visual-editor-area strong {
  font-weight: bold;
  color: #000;
}

.visual-editor-area em {
  font-style: italic;
}

.visual-editor-area u {
  text-decoration: underline;
}

/* ========================================
   编辑区列表样式（基准样式 - 预览区必须复用）
   ======================================== */
.visual-editor-area :deep(.interactive-list) {
  margin: 12px 0;                      /* 核心属性 */
  padding-left: 24px;                  /* 核心属性：缩进距离 */
  list-style-position: outside;        /* 核心属性：项目符号位置 */
}

.visual-editor-area :deep(.interactive-list.nested) {
  margin: 6px 0;
}

.visual-editor-area :deep(.interactive-list li) {
  margin: 6px 0;                       /* 核心属性：列表项间距 */
  padding: 4px 8px;                    /* 核心属性：列表项内边距 */
  min-height: 24px;                    /* 核心属性：最小高度 */
  line-height: 1.8;                    /* 核心属性：行高（必须与预览区一致）*/
  cursor: text;
  transition: background 0.2s;
}

.visual-editor-area :deep(.interactive-list li:hover) {
  background: #f5f5f5;
  border-radius: 4px;
}

.visual-editor-area :deep(.interactive-list li:focus) {
  outline: 2px solid #1890ff;
  outline-offset: 2px;
  border-radius: 4px;
  background: #e6f7ff;
}

/* 有序列表编号样式（核心属性 - 预览区必须复用）*/
.visual-editor-area :deep(ol.interactive-list) {
  list-style-type: decimal;            /* 核心属性：数字编号格式 */
}

.visual-editor-area :deep(ol.interactive-list.nested) {
  list-style-type: lower-alpha;        /* 嵌套列表使用字母 */
}

/* 无序列表项目符号样式（核心属性 - 预览区必须复用）*/
.visual-editor-area :deep(ul.interactive-list) {
  list-style-type: disc;               /* 核心属性：实心圆点 */
}

.visual-editor-area :deep(ul.interactive-list.nested) {
  list-style-type: circle;             /* 嵌套列表使用空心圆 */
}

/* 可视化表格样式 */
.visual-editor-area :deep(.interactive-table-wrapper) {
  margin: 16px 0;
  position: relative;
  overflow-x: auto;
}

.visual-editor-area :deep(.interactive-table) {
  border-collapse: collapse;
  width: 100%;
  border: 2px solid #d9d9d9;
  background: #fff;
  transition: all 0.3s;
}

.visual-editor-area :deep(.interactive-table:hover) {
  box-shadow: 0 4px 16px rgba(24, 144, 255, 0.15);
}

.visual-editor-area :deep(.interactive-table th),
.visual-editor-area :deep(.interactive-table td) {
  border: 1px solid #d9d9d9;
  padding: 10px 12px;
  min-width: 100px;
  cursor: text;
  transition: background 0.2s;
}

.visual-editor-area :deep(.interactive-table th) {
  background: #fafafa;
  font-weight: 600;
  text-align: left;
}

.visual-editor-area :deep(.interactive-table td:hover),
.visual-editor-area :deep(.interactive-table th:hover) {
  background: #e6f7ff;
}

.visual-editor-area :deep(.interactive-table td:focus),
.visual-editor-area :deep(.interactive-table th:focus) {
  outline: 2px solid #1890ff;
  outline-offset: -2px;
  background: #bae7ff;
}

/* 表格工具栏样式 */
.visual-editor-area :deep(.table-toolbar) {
  position: absolute;
  top: -42px;
  left: 0;
  display: none;
  gap: 6px;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.98);
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  z-index: 100;
  align-items: center;
  flex-wrap: wrap;
  animation: slideDown 0.3s ease-out;
}

.visual-editor-area :deep(.table-toolbar-btn) {
  padding: 6px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background: #fff;
  color: #262626;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.3s;
  white-space: nowrap;
}

.visual-editor-area :deep(.table-toolbar-btn:hover) {
  border-color: #1890ff;
  background: #e6f7ff;
  transform: translateY(-1px);
}

.markdown-preview {
  padding: 16px;
  min-height: 200px;
  background: #fff;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  line-height: 1.8;
}

.preview-container h2 {
  margin-bottom: 16px;
  font-size: 24px;
}

.preview-meta {
  color: #666;
  font-size: 14px;
  margin-bottom: 16px;
}

.preview-content {
  padding: 16px 0;
  line-height: 1.8;
}

.preview-attachments {
  margin-top: 16px;
}

.preview-attachments h4 {
  margin-bottom: 8px;
}

/* ========================================
   定时发布区域 - 时间选择区域样式
   ======================================== */
:deep(.scheduled-switch.ant-switch) {
  background: #D9D9D9;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

:deep(.scheduled-switch.ant-switch-checked) {
  background: #3A86FF;
}

:deep(.scheduled-switch .ant-switch-handle) {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}

/* 时间选择区域 - 渐显动画 */
.time-selection-area {
  margin-top: 15px;
  animation: fadeInDown 0.3s ease;
}

@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 快捷时间标签 - 便签式设计 */
.quick-time-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}

.time-tag {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  font-size: 13px;
  color: #999;
  background: transparent;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  user-select: none;
}

.time-tag:hover {
  color: #3A86FF;
  background: #F0F7FF;
}

.time-tag-active {
  color: #3A86FF !important;
  background: #E8F4FF !important;
  font-weight: 500;
}

/* 自定义时间入口 - 文字+图标 */
.custom-time-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  font-size: 13px;
  color: #999;
  background: transparent;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  user-select: none;
  position: relative;
}

.custom-time-trigger:hover {
  color: #3A86FF;
  background: #F0F7FF;
}

.custom-time-trigger:hover::after {
  content: '';
  position: absolute;
  bottom: 4px;
  left: 14px;
  right: 14px;
  height: 1px;
  background: #3A86FF;
  animation: underlineSlide 0.3s ease;
}

@keyframes underlineSlide {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

.custom-time-active {
  color: #3A86FF !important;
  background: #E8F4FF !important;
  font-weight: 500;
}

.custom-time-icon {
  color: #3A86FF;
  font-size: 14px;
}

/* 已选时间条 - 临时便签式 */
.selected-time-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  margin-top: 12px;
  background: #FFFFFF;
  border: 1px solid #E8E8E8;
  border-radius: 4px;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.time-bar-icon {
  color: #3A86FF;
  font-size: 14px;
}

.time-bar-text {
  flex: 1;
  font-size: 13px;
  color: #333;
  font-weight: 500;
}

.time-bar-clear {
  font-size: 12px;
  color: #FF7875;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 3px;
  transition: all 0.2s ease;
}

.time-bar-clear:hover {
  color: #FF4D4F;
  background: #FFF1F0;
}

/* 说明文字 - 随手备注式 */
.time-hint-note {
  font-size: 12px;
  color: #888;
  margin-top: 12px;
  padding-left: 2px;
  font-style: italic;
}

/* 自定义时间选择器模态框样式 */
.custom-time-picker-content {
  padding: 12px 0;
}

.time-tips {
  margin-top: 20px;
  padding: 12px 16px;
  background: #fffbe6;
  border-radius: 4px;
}

.time-tips p {
  margin: 0 0 8px 0;
  font-weight: 500;
  color: #d48806;
}

.time-tips ul {
  margin: 0;
  padding-left: 20px;
  color: #8c8c8c;
  font-size: 13px;
}

.time-tips li {
  margin: 4px 0;
  list-style-type: disc;
}

/* 图片原图预览样式 */
.image-preview-container {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 400px;
}

.preview-image {
  max-width: 100%;
  max-height: 85vh;
  height: auto;
  cursor: zoom-out;
  border-radius: 4px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
  transition: transform 0.3s ease;
  animation: zoomIn 0.3s ease-out;
}

@keyframes zoomIn {
  from {
    opacity: 0;
    transform: scale(0.8);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.preview-image:hover {
  transform: scale(1.02);
}

.preview-tips {
  margin-top: 16px;
  padding: 8px 16px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 4px;
  color: #262626;
  font-size: 13px;
  animation: fadeIn 0.5s ease-in 0.3s both;
}

/* 尺寸选择按钮悬停效果（增强视觉反馈）*/
.size-preset-btn:hover {
  border-color: #1890ff !important;
  transform: translateY(-2px) scale(1.02);
  box-shadow: 0 4px 12px rgba(24, 144, 255, 0.35);
}

.size-preset-btn:active {
  transform: translateY(0) scale(0.98);
}

/* 快捷尺寸网格布局优化 */
.image-size-selector .size-presets button {
  text-align: center;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}

/* 自定义宽度输入框样式优化 */
#custom-width-input:focus {
  border-color: #1890ff;
  outline: none;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
}

/* 表格配置对话框样式 */
.table-config-content {
  padding: 12px 0;
}

.table-preview-hint {
  margin-top: 16px;
  padding: 12px 16px;
  background: #e6f7ff;
  border-left: 4px solid #1890ff;
  border-radius: 4px;
}

/* ========================================
   单选按钮组 - 自然状态区分（去掉下划线）
   ======================================== */
:deep(.ant-radio-group) {
  display: flex;
  gap: 32px;
}

/* 单选按钮 - 自然状态区分（去掉下划线）*/
:deep(.ant-radio-wrapper) {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  transition: all 0.2s ease;
  position: relative;
  padding: 6px 0;
  border-bottom: none !important; /* 强制去掉下划线 */
}

/* 单选框圆形样式优化 */
:deep(.ant-radio) {
  margin-right: 10px; /* 手工微调：文字略右移 */
  position: relative;
  left: -2px; /* 手工微调：选框略左移 */
}

:deep(.ant-radio-inner) {
  width: 18px;
  height: 18px;
  border: 1.5px solid #D9D9D9;
  transition: all 0.3s ease;
}

/* 选中状态 - 蓝色填充圆形 */
:deep(.ant-radio-checked .ant-radio-inner) {
  border-color: #46B5D1;
  background-color: #46B5D1;
}

:deep(.ant-radio-checked .ant-radio-inner::after) {
  background-color: #fff;
}

/* 文字样式 */
:deep(.ant-radio-wrapper span:last-child) {
  position: relative;
  color: #666;
  transition: all 0.3s ease;
  border-bottom: none !important; /* 强制去掉下划线 */
  padding-bottom: 0 !important;
  left: 2px; /* 手工微调：文字略右移 */
}

:deep(.ant-radio-checked + span) {
  color: #46B5D1;
  font-weight: 500;
}

:deep(.ant-radio-wrapper:hover .ant-radio-inner) {
  border-color: #79D4E8;
}

/* ========================================
   功能按钮 - 圆角+浅灰背景，hover主色填充
   ======================================== */
:deep(.ant-btn) {
  border-radius: 6px;
  transition: all 0.3s ease;
}

:deep(.ant-btn-default) {
  background: #F5F5F5; /* 浅灰背景 */
  border: 1px solid #E8E8E8;
  color: #333;
}

:deep(.ant-btn-default:hover) {
  background: #3A86FF; /* hover时主色填充 */
  border-color: #3A86FF;
  color: white;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(58, 134, 255, 0.15);
}

:deep(.ant-btn-primary) {
  background: #3A86FF;
  border-color: #3A86FF;
}

:deep(.ant-btn-primary:hover) {
  background: #2E6FDB;
  border-color: #2E6FDB;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(58, 134, 255, 0.15);
}

/* 清除按钮 - 红色文字+无背景 */
:deep(.ant-btn-link.clear-btn) {
  color: #FF4D4F;
  background: transparent;
  border: none;
  padding: 4px 8px;
}

:deep(.ant-btn-link.clear-btn:hover) {
  color: #CF1322;
  background: rgba(255, 77, 79, 0.05);
  transform: none; /* 不上浮，弱化存在感 */
}

/* ========================================
   辅助说明文字 - 12px, #999, 底部显示
   ======================================== */
.tip {
  font-size: 12px;
  color: var(--text-hint);
  margin-top: 8px;
  line-height: 1.6;
}

/* 辅助说明文字 - 12px, #999, 底部显示 */
.tip {
  font-size: 12px;
  color: #999; /* 辅助说明色 */
  margin-top: 8px;
  line-height: 1.6;
}

.time-tips {
  font-size: 12px;
  color: #999;
  margin-top: 12px;
  padding: 12px;
  background: #F9F9F9;
  border-radius: 4px;
}

.time-tips p {
  margin-bottom: 6px;
  font-weight: 400;
  color: #666; /* 次要文字色 */
}

.time-tips ul {
  margin: 0;
  padding-left: 20px;
}

.time-tips li {
  margin: 4px 0;
  line-height: 1.6;
}

/* ========================================
   富文本编辑器工具栏 - 分组布局+hover动画
   ======================================== */
.editor-toolbar {
  background: #FFFFFF;
  border: 1px solid #E8E8E8;
  border-radius: 6px;
  padding: 12px;
  margin-bottom: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.editor-toolbar :deep(.ant-space) {
  display: flex;
  flex-wrap: wrap;
  gap: 8px; /* 按钮间距，分组布局 */
}

/* 工具栏按钮分组 */
.editor-toolbar :deep(.ant-btn) {
  border-radius: 4px;
  background: #F5F5F5;
  border: 1px solid #E8E8E8;
  transition: all 0.2s ease;
}

.editor-toolbar :deep(.ant-btn:hover) {
  transform: translateY(-2px); /* 轻微上浮 */
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 添加阴影 */
  background: #3A86FF;
  color: white;
  border-color: #3A86FF;
}

/* 标题按钮组 - 特殊样式（添加分割线）*/
.editor-toolbar :deep(.ant-btn[style*="min-width: 80px"]) {
  background: #667EEA; /* 渐变背景改为纯色 */
  color: white;
  border: none;
  border-right: 1px solid rgba(255, 255, 255, 0.2); /* 按钮间分割线 */
  font-weight: 500;
  margin-right: 12px;
}

.editor-toolbar :deep(.ant-btn[style*="min-width: 80px"]:last-of-type) {
  border-right: none; /* 最后一个按钮不显示分割线 */
}

.editor-toolbar :deep(.ant-btn[style*="min-width: 80px"]:hover) {
  background: #5568D3;
  transform: translateY(-3px) scale(1.02); /* hover时放大并显示样式预览 */
  box-shadow: 0 6px 12px rgba(102, 126, 234, 0.3);
}

/* 预览区的表格和列表样式 - 与编辑区完全一致 */
.rich-preview-area :deep(.interactive-table-wrapper),
.preview-content :deep(.interactive-table-wrapper) {
  margin: 16px 0;
  overflow-x: auto;
  position: relative;
}

.rich-preview-area :deep(.interactive-table),
.preview-content :deep(.interactive-table) {
  border-collapse: collapse;
  width: 100%;
  border: 2px solid #d9d9d9;
  background: #fff;
}

.rich-preview-area :deep(.interactive-table th),
.rich-preview-area :deep(.interactive-table td),
.preview-content :deep(.interactive-table th),
.preview-content :deep(.interactive-table td) {
  border: 1px solid #d9d9d9;
  padding: 10px 12px;
  min-width: 100px;
  text-align: left;
}

.rich-preview-area :deep(.interactive-table th),
.preview-content :deep(.interactive-table th) {
  background: #fafafa;
  font-weight: 600;
}

/* 预览区列表样式 - 与编辑区完全一致 */
.rich-preview-area :deep(.interactive-list),
.preview-content :deep(.interactive-list) {
  margin: 12px 0;
  padding-left: 24px;
  list-style-position: outside;
}

.rich-preview-area :deep(.interactive-list.nested),
.preview-content :deep(.interactive-list.nested) {
  margin: 6px 0;
}

.rich-preview-area :deep(.interactive-list li),
.preview-content :deep(.interactive-list li) {
  margin: 6px 0;
  padding: 4px 8px;
  min-height: 24px;
}

.rich-preview-area :deep(ol.interactive-list),
.preview-content :deep(ol.interactive-list) {
  list-style-type: decimal;
}

.rich-preview-area :deep(ol.interactive-list.nested),
.preview-content :deep(ol.interactive-list.nested) {
  list-style-type: lower-alpha;
}

.rich-preview-area :deep(ul.interactive-list),
.preview-content :deep(ul.interactive-list) {
  list-style-type: disc;
}

.rich-preview-area :deep(ul.interactive-list.nested),
.preview-content :deep(ul.interactive-list.nested) {
  list-style-type: circle;
}

/* ========== 移动端适配优化 ========== */

/* 移动端工具栏按钮优化 - 大标题/中标题/小标题按钮放大点击区域 */
/* ========================================
   移动端工具栏优化 - 大标题/中标题/小标题按钮放大点击区域
   ======================================== */
@media (max-width: 768px) {
  /* 标题按钮特别优化 - 放大点击区域 */
  .editor-toolbar .ant-btn[style*="min-width: 80px"] {
    min-width: 80px !important;
    min-height: 40px !important;
    padding: 8px 16px !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    touch-action: manipulation; /* 优化触摸响应 */
  }
  
  /* 工具栏按钮间距增加 */
  .editor-toolbar .ant-space {
    gap: 8px !important;
    flex-wrap: wrap;
  }
  
  /* 标题按钮置于首位，单独一行 */
  .editor-toolbar {
    padding: 12px;
  }
  
  /* 编辑器区域优化 */
  .visual-editor-area {
    min-height: 400px;
    font-size: 16px; /* 移动端字体稍大 */
  }
  
  /* 预览区域优化 - 与编辑区一致 */
  .rich-preview-area {
    min-height: 400px;
    font-size: 16px;
  }
  
  /* ========================================
   输入框优化 - 公告标题输入框只保留最外层框
   ======================================== */
  /* 公告标题输入框 - 只保留最外层框 */
  :deep(.ant-form-item[name="title"] .ant-input) {
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    padding: 8px 12px;
    transition: all 0.3s ease;
    background: #fff;
  }
  
  :deep(.ant-form-item[name="title"] .ant-input:hover) {
    border-color: #40a9ff;
  }
  
  :deep(.ant-form-item[name="title"] .ant-input:focus) {
    border-color: #1890ff;
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
    outline: none;
  }
  
  /* 其他输入框保持无边框设计 */
  :deep(.ant-input-textarea textarea) {
    border: none;
    border-radius: 0;
    padding-bottom: 8px;
    transition: all 0.3s ease;
    background: transparent;
  }
  
  :deep(.ant-input-textarea textarea:hover) {
    background: rgba(0, 0, 0, 0.02);
  }
  
  :deep(.ant-input-textarea-focused textarea) {
    box-shadow: none;
    outline: none;
  }
  
  /* 输入提示文字样式 */
  :deep(.ant-form-item-explain),
  :deep(.ant-form-item-extra) {
    margin-top: 6px;
    font-size: 12px;
    color: #999;
  }
  
  /* 字数统计提示 - 移至输入框下方 */
  :deep(.ant-input-textarea-show-count::after) {
    position: absolute;
    bottom: -20px;
    right: 0;
    font-size: 12px;
    color: var(--text-hint);
  }
  
  /* 标题样式移动端适配（编辑区与预览区完全同步）*/
  .visual-editor-area :deep([data-heading-level="large"]),
  .rich-preview-area :deep([data-heading-level="large"]) {
    font-size: 20px !important; /* 移动端大标题稍大 */
  }
  
  .visual-editor-area :deep([data-heading-level="medium"]),
  .rich-preview-area :deep([data-heading-level="medium"]) {
    font-size: 18px !important;
  }
  
  .visual-editor-area :deep([data-heading-level="small"]),
  .rich-preview-area :deep([data-heading-level="small"]) {
    font-size: 16px !important;
  }
  
  /* 文本内容块移动端适配（编辑区与预览区完全同步）*/
  .visual-editor-area :deep(.text-content-block),
  .rich-preview-area :deep(.text-content-block) {
    font-size: 16px !important;
  }
  
  /* 表格样式移动端适配（编辑区与预览区完全同步）*/
  .visual-editor-area :deep(.interactive-table th),
  .visual-editor-area :deep(.interactive-table td),
  .rich-preview-area :deep(.interactive-table th),
  .rich-preview-area :deep(.interactive-table td) {
    padding: 8px !important;
    font-size: 14px !important;
  }
}

/* 超小屏幕适配 */
@media (max-width: 480px) {
  .editor-toolbar .ant-btn {
    padding: 6px 12px !important;
  }
  
  .visual-editor-area {
    padding: 12px;
    min-height: 300px;
  }
}
</style>
